1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/core-module/11-tr.html
2019-08-31 13:56:36 +01:00

378 lines
47 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>11/itpc</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '11/tr' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#11">Chapter 11: Predicate Calculus</a></li><li><b>Terms</b></li></ul><p class="purpose">Terms are the representations of values in predicate calculus: variables, constants or functions of other terms.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP4">&#167;4. Creating new terms</a></li><li><a href="#SP5">&#167;5. Copying</a></li><li><a href="#SP6">&#167;6. Variable letters</a></li><li><a href="#SP7">&#167;7. Underlying terms</a></li><li><a href="#SP8">&#167;8. Adjective-noun conversions</a></li><li><a href="#SP10">&#167;10. Compiling terms</a></li><li><a href="#SP11">&#167;11. Debugging terms</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Recall that a "term" can be anything which is a constant, can be a
variable, or can be a function f_B(t) of another term t. Our
representation of this as a data structure therefore falls into three
cases. At all times exactly one of the three relevant fields, <code class="display"><span class="extract">variable</span></code>,
<code class="display"><span class="extract">constant</span></code> and <code class="display"><span class="extract">function</span></code> is used.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Variables are represented by the numbers 0 to 25, and <code class="display"><span class="extract">-1</span></code> means
"not a variable".
</li></ul>
<ul class="items"><li>(b) Constants are pointers to <code class="display"><span class="extract">specification</span></code> structures of main
type <code class="display"><span class="extract">VALUE</span></code>, and <code class="display"><span class="extract">NULL</span></code> means "not a constant".
</li></ul>
<ul class="items"><li>(c) Functions are pointers to <code class="display"><span class="extract">pcalc_func</span></code> structures (see below), and
<code class="display"><span class="extract">NULL</span></code> means "not a function".
</li></ul>
<p class="inwebparagraph">Cinders are discussed in "Cinders and Deferrals", and can be ignored for now.
</p>
<p class="inwebparagraph">In order to verify that a proposition makes sense and does not mix up
incompatible kinds of value, we will need to type-check it, and one part
of that involves assigning a kind of value K to every term t occurring
in the proposition. This calculation does involve some work, so we cache
the result in the <code class="display"><span class="extract">term_checked_as_kind</span></code> field, in order that we only have
to work it out once.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pcalc_term</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">variable</span><span class="plain">; </span> <span class="comment">0 to 25, or <code class="display"><span class="extract">-1</span></code> for "not a variable"</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">constant</span><span class="plain">; </span> <span class="comment">or <code class="display"><span class="extract">NULL</span></code> for "not a constant"</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pcalc_func</span><span class="plain"> *</span><span class="identifier">function</span><span class="plain">; </span> <span class="comment">or <code class="display"><span class="extract">NULL</span></code> for "not a function of another term"</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cinder</span><span class="plain">; </span> <span class="comment">complicated, this: used to worry about scope of I6 local variables</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">term_checked_as_kind</span><span class="plain">; </span> <span class="comment">or <code class="display"><span class="extract">NULL</span></code> if unchecked</span>
<span class="plain">} </span><span class="reserved">pcalc_term</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure pcalc_term is accessed in 11/ap, 11/pr, 11/bas, 11/sc, 11/sm, 11/tcp, 12/ter, 12/ap, 12/is, 12/ca, 12/cad, 12/cdp, 15/tpr and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The <code class="display"><span class="extract">pcalc_func</span></code> structure represents a usage of a function inside a term.
Terms such as f_A(f_B(f_C(x))) often occur, so a typical term might be
stored as
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(1) A <code class="display"><span class="extract">pcalc_term</span></code> structure which has a <code class="display"><span class="extract">function</span></code> field pointing to
</li><li>(2) A <code class="display"><span class="extract">pcalc_func</span></code> structure whose <code class="display"><span class="extract">bp</span></code> field points to A, and whose <code class="display"><span class="extract">fn_of</span></code>
field is
</li><li>(3) A <code class="display"><span class="extract">pcalc_term</span></code> structure which has a <code class="display"><span class="extract">function</span></code> field pointing to
</li><li>(4) A <code class="display"><span class="extract">pcalc_func</span></code> structure whose <code class="display"><span class="extract">bp</span></code> field points to B, and whose <code class="display"><span class="extract">fn_of</span></code>
field is
</li><li>(5) A <code class="display"><span class="extract">pcalc_term</span></code> structure which has a <code class="display"><span class="extract">function</span></code> field pointing to
</li><li>(6) A <code class="display"><span class="extract">pcalc_func</span></code> structure whose <code class="display"><span class="extract">bp</span></code> field points to C, and whose <code class="display"><span class="extract">fn_of</span></code>
field is
</li><li>(7) A <code class="display"><span class="extract">pcalc_term</span></code> structure which has a <code class="display"><span class="extract">variable</span></code> field set to 0 (which is x).
</li></ul>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pcalc_func</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">; </span> <span class="comment">the predicate B such that this is f_B(t)</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">fn_of</span><span class="plain">; </span> <span class="comment">the term t such that this is f_B(t)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">from_term</span><span class="plain">; </span> <span class="comment">whether t is term 0 or 1 of B</span>
<span class="plain">} </span><span class="reserved">pcalc_func</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure pcalc_func is accessed in 11/bas, 11/sm, 11/tcp, 12/ap, 12/ca, 12/cad, 12/cdp and here.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Creating new terms. </b></p>
<pre class="display">
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">) {</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">; </span>&lt;<span class="cwebmacro">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">v</span><span class="plain"> &lt; 0) || (</span><span class="identifier">v</span><span class="plain"> &gt;= 26)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad variable term created"</span><span class="plain">);</span>
<span class="identifier">pt</span><span class="element">.variable</span><span class="plain"> = </span><span class="identifier">v</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">; </span>&lt;<span class="cwebmacro">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="identifier">pt</span><span class="element">.constant</span><span class="plain"> = </span><span class="identifier">c</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::new_function</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">ptof</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">; </span>&lt;<span class="cwebmacro">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">pcalc_func</span><span class="plain"> *</span><span class="identifier">pf</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">pcalc_func</span><span class="plain">);</span>
<span class="identifier">pf</span><span class="plain">-</span><span class="element">&gt;bp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">; </span><span class="identifier">pf</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain"> = </span><span class="identifier">ptof</span><span class="plain">; </span><span class="identifier">pf</span><span class="plain">-</span><span class="element">&gt;from_term</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
<span class="identifier">pt</span><span class="element">.function</span><span class="plain"> = </span><span class="identifier">pf</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::new_variable is used in <a href="#SP8">&#167;8</a>, 9/ma (<a href="9-ma.html#SP3_3_39_5">&#167;3.3.39.5</a>), 9/imp (<a href="9-imp.html#SP7_1_3">&#167;7.1.3</a>), 11/ap (<a href="11-ap.html#SP8">&#167;8</a>, <a href="11-ap.html#SP20">&#167;20</a>, <a href="11-ap.html#SP22">&#167;22</a>), 11/pr (<a href="11-pr.html#SP26">&#167;26</a>, <a href="11-pr.html#SP27">&#167;27</a>), 11/tc (<a href="11-tc.html#SP1">&#167;1</a>, <a href="11-tc.html#SP2">&#167;2</a>, <a href="11-tc.html#SP3">&#167;3</a>, <a href="11-tc.html#SP4">&#167;4</a>, <a href="11-tc.html#SP5">&#167;5</a>, <a href="11-tc.html#SP7">&#167;7</a>), 11/sc (<a href="11-sc.html#SP3_3">&#167;3.3</a>, <a href="11-sc.html#SP3_7">&#167;3.7</a>), 11/sm (<a href="11-sm.html#SP3_2">&#167;3.2</a>, <a href="11-sm.html#SP4">&#167;4</a>, <a href="11-sm.html#SP8">&#167;8</a>, <a href="11-sm.html#SP10_3_2">&#167;10.3.2</a>), 12/ca (<a href="12-ca.html#SP8">&#167;8</a>), 12/dtd (<a href="12-dtd.html#SP10">&#167;10</a>, <a href="12-dtd.html#SP13">&#167;13</a>), 12/cdp (<a href="12-cdp.html#SP5">&#167;5</a>), 14/ds (<a href="14-ds.html#SP3">&#167;3</a>, <a href="14-ds.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Calculus::Terms::new_constant is used in <a href="#SP8">&#167;8</a>, 4/am (<a href="4-am.html#SP39_1">&#167;39.1</a>), 10/varc (<a href="10-varc.html#SP13">&#167;13</a>), 11/ap (<a href="11-ap.html#SP22">&#167;22</a>), 11/pr (<a href="11-pr.html#SP27">&#167;27</a>), 11/bas (<a href="11-bas.html#SP17">&#167;17</a>), 11/tc (<a href="11-tc.html#SP3">&#167;3</a>, <a href="11-tc.html#SP4">&#167;4</a>), 11/sc (<a href="11-sc.html#SP1">&#167;1</a>, <a href="11-sc.html#SP3_3">&#167;3.3</a>, <a href="11-sc.html#SP3_5">&#167;3.5</a>), 11/sm (<a href="11-sm.html#SP4">&#167;4</a>, <a href="11-sm.html#SP15">&#167;15</a>), 12/is (<a href="12-is.html#SP6">&#167;6</a>, <a href="12-is.html#SP8">&#167;8</a>), 12/cdp (<a href="12-cdp.html#SP5">&#167;5</a>), 15/ma (<a href="15-ma.html#SP13">&#167;13</a>), 25/cii (<a href="25-cii.html#SP3_5_4">&#167;3.5.4</a>).</p>
<p class="endnote">The function Calculus::Terms::new_function is used in <a href="#SP5">&#167;5</a>, 11/sm (<a href="11-sm.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b>Where, in all three cases:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">pt</span><span class="element">.variable</span><span class="plain"> = -1;</span>
<span class="identifier">pt</span><span class="element">.constant</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pt</span><span class="element">.function</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pt</span><span class="element">.cinder</span><span class="plain"> = -1; </span> <span class="comment">that is, no cinder</span>
<span class="identifier">pt</span><span class="element">.term_checked_as_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a> (three times).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Copying. </b></p>
<pre class="display">
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::copy</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">) </span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain"> = </span><span class="identifier">ParseTree::duplicate</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">) </span><span class="identifier">pt</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_function</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">-</span><span class="element">&gt;bp</span><span class="plain">,</span>
<span class="functiontext">Calculus::Terms::copy</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain">), </span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">-</span><span class="element">&gt;from_term</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::copy is used in 11/pr (<a href="11-pr.html#SP14">&#167;14</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Variable letters. </b>The variables 0 to 25 are referred to by the letters x, y, z, a, b,
c, ..., w: this convention is followed both in the debugging log and
in functions compiled into I6 code.
</p>
<p class="inwebparagraph">The number 26 turns up quite often in this chapter, and while it's
normally good style to define named constants, here we're not going
to. 26 is a number which anyone other than a string theorist will
immediately associate with the size of the alphabet. Moreover, we
can't really raise the total, because there are only 26
single-character local variable names in I6, <code class="display"><span class="extract">a</span></code> to <code class="display"><span class="extract">z</span></code>. (Well,
strictly speaking there is also <code class="display"><span class="extract">_</span></code>, but we won't go there.) To have a
variable limit lower than 26 would be artificial, since there are no
memory constraints arguing for it; and in any case a proposition with
27 or more variables would be so huge that it could not be evaluated
at run-time in any remotely plausible length of time. So although the
26-variables-only limit is embedded in Inform, it really is not any
restriction, and it greatly simplifies the code.
</p>
<pre class="display">
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">pcalc_vars</span><span class="plain"> = </span><span class="string">"xyzabcdefghijklmnopqrstuvw"</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Underlying terms. </b>Routines to see if a term is a constant C, or if it is a chain of functions
at the bottom of which is a constant C; and similarly for variables.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Calculus::Terms::constant_underlying</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"null term"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;constant</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;constant</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::constant_underlying</span><span class="plain">(&amp;(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::variable_underlying</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"null term"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;variable</span><span class="plain"> &gt;= 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;variable</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::variable_underlying</span><span class="plain">(&amp;(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::constant_underlying is used in 11/sm (<a href="11-sm.html#SP3">&#167;3</a>, <a href="11-sm.html#SP4">&#167;4</a>), 11/tcp (<a href="11-tcp.html#SP6_1">&#167;6.1</a>), 12/ca (<a href="12-ca.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Calculus::Terms::variable_underlying is used in 11/pr (<a href="11-pr.html#SP23">&#167;23</a>, <a href="11-pr.html#SP25">&#167;25</a>), 11/bas (<a href="11-bas.html#SP4">&#167;4</a>, <a href="11-bas.html#SP10">&#167;10</a>, <a href="11-bas.html#SP15_1">&#167;15.1</a>), 11/sc (<a href="11-sc.html#SP3_2">&#167;3.2</a>), 11/sm (<a href="11-sm.html#SP14">&#167;14</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Adjective-noun conversions. </b>As we shall see, a general unary predicate stores a type-reference
pointer to an adjectival phrase &mdash; the adjective it tests. But
sometimes the same word acts both as adjective and noun in English. In
"the green door", clearly "green" is an adjective; in "the door
is green", it is possibly a noun; in "the colour of the door is
green", it must surely be a noun. Yet these are all really the same
meaning. To cope with this ambiguity, we need a way to convert the
adjectival form of such an adjective into its noun form, and back
again.
</p>
<pre class="display">
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::adj_to_noun_conversion</span><span class="plain">(</span><span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">tr</span><span class="plain">) {</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::get_aph</span><span class="plain">(</span><span class="identifier">tr</span><span class="plain">);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::has_ENUMERATIVE_meaning</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::has_EORP_meaning</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="functiontext">Rvalues::from_property</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(0);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::adj_to_noun_conversion is used in 11/pr (<a href="11-pr.html#SP27">&#167;27</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>And conversely:
</p>
<pre class="display">
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="functiontext">Calculus::Terms::noun_to_adj_conversion</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::Conditions::get_coinciding_property</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">aph</span><span class="plain"> = </span><span class="functiontext">Instances::get_adjectival_phrase</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">AdjectiveUsages::new</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::noun_to_adj_conversion is used in 11/tcp (<a href="11-tcp.html#SP6_7">&#167;6.7</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Compiling terms. </b>We are now ready to compile a general predicate-calculus term, which
may be a constant (perhaps with a cinder marking), a variable or a function
of another term.
</p>
<p class="inwebparagraph">Variables are compiled to I6 locals <code class="display"><span class="extract">x</span></code>, <code class="display"><span class="extract">y</span></code>, <code class="display"><span class="extract">z</span></code>, ...; cindered constants to
<code class="display"><span class="extract">const_0</span></code>, <code class="display"><span class="extract">const_1</span></code>, ... These will only be valid inside a deferred routine
like <code class="display"><span class="extract">Prop_19</span></code>, but that is fine because they cannot arise anywhere else.
If we are compiling an undeferred proposition then all constants are uncindered
and there are no variables (if there were, it would have been deferred).
</p>
<p class="inwebparagraph">Functions f_R(t) are compiled by expanding an I6 schema for f_R with t
as parameter.
</p>
<p class="inwebparagraph">One small wrinkle is that we type-check any use of a phrase to decide a
value, because this might not yet have been checked otherwise.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::emit</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="element">.variable</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::find_pcalc_var</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.variable</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"var is %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">pt</span><span class="element">.variable</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"absent calculus variable"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="element">.cinder</span><span class="plain"> &gt;= 0) {</span>
<span class="functiontext">Calculus::Deferrals::Cinders::emit</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.cinder</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_phrasal</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">))</span>
<span class="functiontext">Dash::check_value</span><span class="plain">(</span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">pt</span><span class="element">.constant</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">) {</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = (</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">)-</span><span class="element">&gt;bp</span><span class="plain">;</span>
<span class="identifier">fn</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_as_function_of_other</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">fn</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_as_function_of_other</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Function of non-functional predicate"</span><span class="plain">);</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_terms</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, &amp;(</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Broken pcalc term"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::emit is used in 12/is (<a href="12-is.html#SP8">&#167;8</a>), 12/cdp (<a href="12-cdp.html#SP2_1_6_1_2_5">&#167;2.1.6.1.2.5</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Debugging terms. </b>The art of this is to be unobtrusive; when a proposition is being logged,
we don't much care about the constant terms, and want to display them
concisely and without fuss.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Terms::log</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;null-term&gt;"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;constant</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;constant</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;cinder</span><span class="plain"> &gt;= 0) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"const_%d"</span><span class="plain">, </span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;cinder</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"'%W'"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$O"</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$P"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">) {</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">-</span><span class="element">&gt;bp</span><span class="plain">;</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_as_function_of_other</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">fn</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_as_function_of_other</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Function of non-functional predicate"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Streams::I6_escapes_enabled</span><span class="plain">(</span><span class="identifier">DL</span><span class="plain">)) {</span>
<span class="functiontext">Calculus::Schemas::log_applied</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, &amp;(</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"{$i:$0}"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">, &amp;(</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;function</span><span class="plain">-</span><span class="element">&gt;fn_of</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;variable</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-</span><span class="element">&gt;variable</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">&lt;26) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"%c"</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]); </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;bad-var=%d&gt;"</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;bad-term&gt;"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Terms::log is used in 1/cm (<a href="1-cm.html#SP5">&#167;5</a>, <a href="1-cm.html#SP6_6">&#167;6.6</a>), 11/ap (<a href="11-ap.html#SP25_3">&#167;25.3</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="11-itpc.html">Back to 'Introduction to Predicate Calculus'</a></li><li><a href="11-ap.html">Continue with 'Atomic Propositions'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>