mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
378 lines
47 KiB
HTML
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">★</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">§1. Definitions</a></li><li><a href="#SP4">§4. Creating new terms</a></li><li><a href="#SP5">§5. Copying</a></li><li><a href="#SP6">§6. Variable letters</a></li><li><a href="#SP7">§7. Underlying terms</a></li><li><a href="#SP8">§8. Adjective-noun conversions</a></li><li><a href="#SP10">§10. Compiling terms</a></li><li><a href="#SP11">§11. Debugging terms</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§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>§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>§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><<span class="cwebmacro">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">v</span><span class="plain"> < 0) || (</span><span class="identifier">v</span><span class="plain"> >= 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><<span class="cwebmacro">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>><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><<span class="cwebmacro">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</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="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">>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">>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">>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">§8</a>, 9/ma (<a href="9-ma.html#SP3_3_39_5">§3.3.39.5</a>), 9/imp (<a href="9-imp.html#SP7_1_3">§7.1.3</a>), 11/ap (<a href="11-ap.html#SP8">§8</a>, <a href="11-ap.html#SP20">§20</a>, <a href="11-ap.html#SP22">§22</a>), 11/pr (<a href="11-pr.html#SP26">§26</a>, <a href="11-pr.html#SP27">§27</a>), 11/tc (<a href="11-tc.html#SP1">§1</a>, <a href="11-tc.html#SP2">§2</a>, <a href="11-tc.html#SP3">§3</a>, <a href="11-tc.html#SP4">§4</a>, <a href="11-tc.html#SP5">§5</a>, <a href="11-tc.html#SP7">§7</a>), 11/sc (<a href="11-sc.html#SP3_3">§3.3</a>, <a href="11-sc.html#SP3_7">§3.7</a>), 11/sm (<a href="11-sm.html#SP3_2">§3.2</a>, <a href="11-sm.html#SP4">§4</a>, <a href="11-sm.html#SP8">§8</a>, <a href="11-sm.html#SP10_3_2">§10.3.2</a>), 12/ca (<a href="12-ca.html#SP8">§8</a>), 12/dtd (<a href="12-dtd.html#SP10">§10</a>, <a href="12-dtd.html#SP13">§13</a>), 12/cdp (<a href="12-cdp.html#SP5">§5</a>), 14/ds (<a href="14-ds.html#SP3">§3</a>, <a href="14-ds.html#SP10">§10</a>).</p>
|
|
|
|
<p class="endnote">The function Calculus::Terms::new_constant is used in <a href="#SP8">§8</a>, 4/am (<a href="4-am.html#SP39_1">§39.1</a>), 10/varc (<a href="10-varc.html#SP13">§13</a>), 11/ap (<a href="11-ap.html#SP22">§22</a>), 11/pr (<a href="11-pr.html#SP27">§27</a>), 11/bas (<a href="11-bas.html#SP17">§17</a>), 11/tc (<a href="11-tc.html#SP3">§3</a>, <a href="11-tc.html#SP4">§4</a>), 11/sc (<a href="11-sc.html#SP1">§1</a>, <a href="11-sc.html#SP3_3">§3.3</a>, <a href="11-sc.html#SP3_5">§3.5</a>), 11/sm (<a href="11-sm.html#SP4">§4</a>, <a href="11-sm.html#SP15">§15</a>), 12/is (<a href="12-is.html#SP6">§6</a>, <a href="12-is.html#SP8">§8</a>), 12/cdp (<a href="12-cdp.html#SP5">§5</a>), 15/ma (<a href="15-ma.html#SP13">§13</a>), 25/cii (<a href="25-cii.html#SP3_5_4">§3.5.4</a>).</p>
|
|
|
|
<p class="endnote">The function Calculus::Terms::new_function is used in <a href="#SP5">§5</a>, 11/sm (<a href="11-sm.html#SP13">§13</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4_1"></a><b>§4.1. </b>Where, in all three cases:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Make new blank term structure pt</span> <span class="cwebmacronumber">4.1</span>> =
|
|
</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">§4</a> (three times).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§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">>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">>fn_of</span><span class="plain">), </span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">-</span><span class="element">>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">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§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>§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">>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">>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">>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">(&(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>function</span><span class="plain">-</span><span class="element">>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">>variable</span><span class="plain"> >= 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>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">>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">(&(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>function</span><span class="plain">-</span><span class="element">>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">§3</a>, <a href="11-sm.html#SP4">§4</a>), 11/tcp (<a href="11-tcp.html#SP6_1">§6.1</a>), 12/ca (<a href="12-ca.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function Calculus::Terms::variable_underlying is used in 11/pr (<a href="11-pr.html#SP23">§23</a>, <a href="11-pr.html#SP25">§25</a>), 11/bas (<a href="11-bas.html#SP4">§4</a>, <a href="11-bas.html#SP10">§10</a>, <a href="11-bas.html#SP15_1">§15.1</a>), 11/sc (<a href="11-sc.html#SP3_2">§3.2</a>), 11/sm (<a href="11-sm.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. Adjective-noun conversions. </b>As we shall see, a general unary predicate stores a type-reference
|
|
pointer to an adjectival phrase — 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">§27</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§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">§6.7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§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"> >= 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"> >= 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">>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">, &(</span><span class="identifier">pt</span><span class="element">.function</span><span class="plain">-</span><span class="element">>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">§8</a>), 12/cdp (<a href="12-cdp.html#SP2_1_6_1_2_5">§2.1.6.1.2.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§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">"<null-term>"</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">>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">>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">>cinder</span><span class="plain"> >= 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">>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">>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">>function</span><span class="plain">-</span><span class="element">>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">, &(</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">>function</span><span class="plain">-</span><span class="element">>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">, &(</span><span class="identifier">pt</span><span class="plain">-</span><span class="element">>function</span><span class="plain">-</span><span class="element">>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">>variable</span><span class="plain"> >= 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">>variable</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"><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">"<bad-var=%d>"</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">"<bad-term>"</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">§5</a>, <a href="1-cm.html#SP6_6">§6.6</a>), 11/ap (<a href="11-ap.html#SP25_3">§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>
|
|
|