mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
667 lines
83 KiB
HTML
667 lines
83 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>11/pr</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/bas' 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>Binding and Substitution</b></li></ul><p class="purpose">To substitute constants into propositions in place of variables, and to apply quantifiers to bind any unbound variables.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP4">§4. Well-formedness</a></li><li><a href="#SP9">§9. Renumbering</a></li><li><a href="#SP12">§12. Binding</a></li><li><a href="#SP13">§13. Substitution</a></li><li><a href="#SP16">§16. A footnote on variable 0</a></li><li><a href="#SP19">§19. Detect locals</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>In any given proposition:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) a variable is unused if it is never mentioned as, or in, any term,
|
|
and is not the variable of any quantifier;
|
|
</li></ul>
|
|
<ul class="items"><li>(b) a variable is bound if it appears as the variable of any <code class="display"><span class="extract">QUANTIFIER_ATOM</span></code>;
|
|
</li></ul>
|
|
<ul class="items"><li>(c) a variable is free if it is used but not bound.
|
|
</li></ul>
|
|
<p class="inwebparagraph">These are mutually exclusive (no two can be true at the same time), and in
|
|
any given proposition, each of the 26 variables is always either unused, bound
|
|
or free.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In this section we are concerned with three operations applied to propositions:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) substitution means replacing each mention of a given variable
|
|
with a given constant: for instance, changing x to 3 throughout
|
|
("substituting x=3"). This has no effect if x is unused, and is
|
|
illegal if x is bound, since it could produce nonsense like "for all 3,
|
|
3 is odd".
|
|
</li></ul>
|
|
<ul class="items"><li>(b) binding means adding a new quantifier to a proposition, ranging
|
|
some variable v. If v were unused this would be unlikely to be sensible
|
|
(it would just make an inefficient way to test the size of the domain set),
|
|
whereas if v were already a bound variable then the result would be a
|
|
proposition which is no longer well-formed. So binding can only be done to
|
|
free variables.
|
|
</li></ul>
|
|
<ul class="items"><li>(c) renumbering means replacing each mention of a given variable v
|
|
with another variable w. Clearly w needs to be initially unused, or we
|
|
could accidentally change "v is greater than w" into "w is greater
|
|
than w". But provided w is unused, the proposition's truth or otherwise
|
|
remains unchanged.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Propositions with free variables are vague, and we would like to get rid
|
|
of them. It can be very difficult to guess their values, just as subtle
|
|
human understanding seems to be needed to interpret pronouns like "it"
|
|
(see the enormous literature on the donkey anaphora problem in
|
|
linguistics). So we aim to translate excerpts of source text into just two
|
|
kinds of proposition:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) an S-proposition which has no free variables — such as the result
|
|
of translating "The tree is in the Courtyard" or "Every door is open";
|
|
</li></ul>
|
|
<ul class="items"><li>(b) an SN-proposition in which only variable 0 (x) is free — such
|
|
as the result of translating "open containers which are in lighted rooms",
|
|
which comes out to a proposition φ(x) testing whether x is one.
|
|
</li></ul>
|
|
<p class="inwebparagraph">Whole English sentences or conditions make S-propositions, but
|
|
descriptions make SN-propositions. (By renumbering, any proposition with one
|
|
free variable can be made into an SN-proposition.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. Well-formedness. </b>It might seem logical to have a routine which takes a proposition φ
|
|
and a variable v and returns its status — unused, free or bound. But this
|
|
would be inefficient, since we want to work with all 26 at once, so instead
|
|
we take a pointer to an array of <code class="display"><span class="extract">int</span></code> which needs to have (at least, but
|
|
probably exactly) 26 entries, and on exit each entry is set to one of the
|
|
following. In the course of doing that, it's easy to test whether variables
|
|
are used properly — a bound variable should occur for the first time in
|
|
its quantification, and should not reoccur once the subexpression holding
|
|
the quantifier has finished. We set the <code class="display"><span class="extract">valid</span></code> flag if all is well.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">UNUSED_VST</span><span class="plain"> 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">FREE_VST</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">BOUND_VST</span><span class="plain"> 3</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">var_states</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">valid</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">unavailable</span><span class="plain">[26], </span><span class="identifier">blevel</span><span class="plain"> = 0, </span><span class="identifier">dummy</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">valid</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">valid</span><span class="plain"> = &</span><span class="identifier">dummy</span><span class="plain">;</span>
|
|
<span class="plain">*</span><span class="identifier">valid</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><26; </span><span class="identifier">j</span><span class="plain">++) { </span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = </span><span class="constant">UNUSED_VST</span><span class="plain">; </span><span class="identifier">unavailable</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = 0; }</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Atoms::element_get_group</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain">) == </span><span class="constant">OPEN_OPERATORS_GROUP</span><span class="plain">) </span><span class="identifier">blevel</span><span class="plain">++;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Atoms::element_get_group</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain">) == </span><span class="constant">CLOSE_OPERATORS_GROUP</span><span class="plain">) {</span>
|
|
<span class="identifier">blevel</span><span class="plain">--;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><26; </span><span class="identifier">j</span><span class="plain">++) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">unavailable</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] > </span><span class="identifier">blevel</span><span class="plain">) </span><span class="identifier">unavailable</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = -1;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>arity</span><span class="plain">; </span><span class="identifier">j</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="functiontext">Calculus::Terms::variable_underlying</span><span class="plain">(&(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">v</span><span class="plain"> >= 26) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"corrupted variable term"</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="reserved">if</span><span class="plain"> (</span><span class="identifier">unavailable</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] == -1) {</span>
|
|
<span class="plain">*</span><span class="identifier">valid</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$o invalid because of %c unavailable\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">]);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain"> == </span><span class="constant">QUANTIFIER_ATOM</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] != </span><span class="constant">UNUSED_VST</span><span class="plain">) {</span>
|
|
<span class="plain">*</span><span class="identifier">valid</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$D: $o invalid because of %c Q for F\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">]);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="constant">BOUND_VST</span><span class="plain">; </span><span class="identifier">unavailable</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="identifier">blevel</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">var_states</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] == </span><span class="constant">UNUSED_VST</span><span class="plain">) </span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="constant">FREE_VST</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::determine_status is used in <a href="#SP5">§5</a>, <a href="#SP6">§6</a>, <a href="#SP7">§7</a>, <a href="#SP8">§8</a>, <a href="#SP11">§11</a>, <a href="#SP12">§12</a>, 11/tcp (<a href="11-tcp.html#SP6_12">§6.12</a>), 12/ap (<a href="12-ap.html#SP9_4">§9.4</a>), 12/cdp (<a href="12-cdp.html#SP2_1_5">§2.1.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>With just a little wrapping, this gives us the test of well-formedness.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::is_well_formed</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">status</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">[26];</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::is_syntactically_valid</span><span class="plain">(</span><span class="identifier">prop</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">FALSE</span><span class="plain">;</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">, &</span><span class="identifier">status</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">status</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Variable usage malformed\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</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">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::is_well_formed is used in <a href="#SP15">§15</a>, 11/sc (<a href="11-sc.html#SP1_14">§1.14</a>, <a href="11-sc.html#SP3_2">§3.2</a>), 11/tcp (<a href="11-tcp.html#SP6">§6</a>), 12/dtd (<a href="12-dtd.html#SP28">§28</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>Occasionally we really do care only about one of the 26 variables:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::status</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</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">int</span><span class="plain"> </span><span class="identifier">var_states</span><span class="plain">[26];</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">v</span><span class="plain"> == -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">UNUSED_VST</span><span class="plain">;</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">var_states</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">var_states</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">];</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::status is used in <a href="#SP15_1">§15.1</a>, 11/sc (<a href="11-sc.html#SP3_2">§3.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>To distinguish sentences from descriptions, the following can be informative:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::number_free</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">var_states</span><span class="plain">[26], </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">;</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0, </span><span class="identifier">c</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><26; </span><span class="identifier">j</span><span class="plain">++) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="constant">FREE_VST</span><span class="plain">) </span><span class="identifier">c</span><span class="plain">++;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS_WORKINGS</span><span class="plain">, </span><span class="string">"There %s %d free variable%s in $D\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="plain">(</span><span class="identifier">c</span><span class="plain">==1)?</span><span class="string">"is"</span><span class="plain">:</span><span class="string">"are"</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">, (</span><span class="identifier">c</span><span class="plain">==1)?</span><span class="string">""</span><span class="plain">:</span><span class="string">"s"</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::number_free is used in 9/ma (<a href="9-ma.html#SP3_3_39_5">§3.3.39.5</a>), 11/sc (<a href="11-sc.html#SP1_14">§1.14</a>, <a href="11-sc.html#SP3_2">§3.2</a>), 12/dtd (<a href="12-dtd.html#SP28">§28</a>), 14/ds (<a href="14-ds.html#SP6">§6</a>), 14/ds2 (<a href="14-ds2.html#SP25">§25</a>), 22/dptd (<a href="22-dptd.html#SP20_2_3">§20.2.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>While this gives us a new variable which can safely be added to an existing
|
|
proposition:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::find_unused</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">var_states</span><span class="plain">[26], </span><span class="identifier">j</span><span class="plain">;</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><26; </span><span class="identifier">j</span><span class="plain">++) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="constant">UNUSED_VST</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> 25; </span> <span class="comment">the best we can do: it avoids crashes, at least...</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::find_unused is used in 11/sc (<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>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. Renumbering. </b>Another "vector operation" on variables: to renumber them throughout a
|
|
proposition according to a map array. If <code class="display"><span class="extract">renumber_map[j]</span></code> is -1, make
|
|
no change; otherwise each instance of variable j should be changed to
|
|
this new number.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Note that because <code class="display"><span class="extract">QUANTIFIER_ATOM</span></code>s store the variable being quantified
|
|
as a term, the following changes quantification variables as well as
|
|
predicate terms, which is as it should be.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::vars_map</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">renumber_map</span><span class="plain">, </span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">preserving</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>arity</span><span class="plain">; </span><span class="identifier">j</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">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]);</span>
|
|
<span class="functiontext">Calculus::Variables::term_map</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">, </span><span class="identifier">renumber_map</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">preserving</span><span class="plain">) </span><span class="functiontext">Calculus::Variables::term_map</span><span class="plain">(</span><span class="identifier">preserving</span><span class="plain">, </span><span class="identifier">renumber_map</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::term_map</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">int</span><span class="plain"> *</span><span class="identifier">renumber_map</span><span class="plain">) {</span>
|
|
<span class="reserved">while</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="identifier">pt</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="reserved">int</span><span class="plain"> </span><span class="identifier">nv</span><span class="plain"> = </span><span class="identifier">renumber_map</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">pt</span><span class="plain">-</span><span class="element">>variable</span><span class="plain"> >= 0) && (</span><span class="identifier">nv</span><span class="plain"> >= 0)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nv</span><span class="plain"> >= 26) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed renumbering map"</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="identifier">nv</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::vars_map is used in <a href="#SP10">§10</a>, <a href="#SP11">§11</a>.</p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::term_map appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>The following takes any proposition and edits it so that the variables
|
|
used are the lowest-numbered ones; moreover, variables are introduced
|
|
in numerical order — that is, the first mentioned will be x, then the
|
|
next introduced will be y, and so on.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::renumber</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">preserving</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">renumber_map</span><span class="plain">[26];</span>
|
|
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><26; </span><span class="identifier">j</span><span class="plain">++) </span><span class="identifier">renumber_map</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = -1;</span>
|
|
|
|
<span class="identifier">k</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>arity</span><span class="plain">; </span><span class="identifier">j</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="functiontext">Calculus::Terms::variable_underlying</span><span class="plain">(&(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[</span><span class="identifier">j</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">renumber_map</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] == -1)) </span><span class="identifier">renumber_map</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="identifier">k</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="functiontext">Calculus::Variables::vars_map</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">renumber_map</span><span class="plain">, </span><span class="identifier">preserving</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::renumber is used in <a href="#SP12">§12</a>, 11/sc (<a href="11-sc.html#SP1_14">§1.14</a>, <a href="11-sc.html#SP2">§2</a>), 11/sm (<a href="11-sm.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>This more complicated routine renumbers bound variables in one proposition
|
|
in order to guarantee that none of them coincides with a variable used
|
|
in a second proposition. This is needed in order to take the conjunction of
|
|
two propositions, because "for all x, x is a door" and "there exists x
|
|
such that x is a container" mean different things by x; they can only
|
|
be combined in a single proposition if one of the x variables is changed
|
|
to, say, y.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The surprising thing here is the asymmetry. Why do we only renumber to avoid
|
|
clashes with bound variables in <code class="display"><span class="extract">prop</span></code> — why not free ones as well? The
|
|
answer is that we use a form of conjunction in Inform which assumes that a
|
|
free variable in φ has the same meaning as it does in ψ; thus in
|
|
conjoining "open" with "lockable" we assume that the same thing is meant
|
|
to be both open and lockable. If we renumbered to avoid clashes in free
|
|
variables, we would produce a proposition meaning that one unknown thing is
|
|
open, and another one lockable: that would have two free variables and be
|
|
much harder to interpret.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">If we pass a <code class="display"><span class="extract">query</span></code> parameter which is a valid variable number, the routine
|
|
returns its new identity when renumbered.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::renumber_bound</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">not_to_overlap</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">query</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">prop_vstates</span><span class="plain">[26], </span><span class="identifier">nto_vstates</span><span class="plain">[26], </span><span class="identifier">renumber_map</span><span class="plain">[26];</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">next_unused</span><span class="plain">;</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">prop_vstates</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">not_to_overlap</span><span class="plain">, </span><span class="identifier">nto_vstates</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0, </span><span class="identifier">next_unused</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><26; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">prop_vstates</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="constant">BOUND_VST</span><span class="plain">) && (</span><span class="identifier">nto_vstates</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] != </span><span class="constant">UNUSED_VST</span><span class="plain">)) {</span>
|
|
<<span class="cwebmacro">Advance to the next variable not used in either proposition</span> <span class="cwebmacronumber">11.1</span>><span class="plain">;</span>
|
|
<span class="identifier">renumber_map</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = </span><span class="identifier">next_unused</span><span class="plain">++;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">renumber_map</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = -1;</span>
|
|
|
|
<span class="functiontext">Calculus::Variables::vars_map</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">renumber_map</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">query</span><span class="plain"> == -1) </span><span class="reserved">return</span><span class="plain"> -1;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">renumber_map</span><span class="plain">[</span><span class="identifier">query</span><span class="plain">] == -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">query</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">renumber_map</span><span class="plain">[</span><span class="identifier">query</span><span class="plain">];</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::renumber_bound is used in 11/pr (<a href="11-pr.html#SP16">§16</a>), 11/sc (<a href="11-sc.html#SP1_13">§1.13</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11_1"></a><b>§11.1. </b>Again, we fall back on variable 25 if we run out. (This can only happen if
|
|
the conjunction of the two propositions had 26 variables.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Advance to the next variable not used in either proposition</span> <span class="cwebmacronumber">11.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=</span><span class="identifier">next_unused</span><span class="plain">; (</span><span class="identifier">k</span><span class="plain"><26) &&</span>
|
|
<span class="plain">(!((</span><span class="identifier">prop_vstates</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] == </span><span class="constant">UNUSED_VST</span><span class="plain">) && (</span><span class="identifier">nto_vstates</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] == </span><span class="constant">UNUSED_VST</span><span class="plain">))); </span><span class="identifier">k</span><span class="plain">++) ;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> == 26) </span><span class="identifier">next_unused</span><span class="plain"> = 25; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">next_unused</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP11">§11</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. Binding. </b>In this routine, we look for free variables and preface the proposition
|
|
with ∃ quantifiers to bind them. For instance, open(x) becomes
|
|
∃ x: open(x).
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We first renumber the proposition's variables from left to right, and
|
|
then quantify in reverse order — thus starting with the innermost free
|
|
variable and working outwards (i.e., towards the left). Since at each
|
|
stage we are prefacing the proposition, though, the net effect is that in
|
|
the final proposition the previously free variables are bound in increasing
|
|
order. For instance:
|
|
in(x, y) -->
|
|
∃ y: in(x, y) -->
|
|
∃ x: ∃ y: in(x, y)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Calculus::Variables::bind_existential</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">,</span>
|
|
<span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">preserving</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">var_states</span><span class="plain">[26], </span><span class="identifier">j</span><span class="plain">;</span>
|
|
|
|
<span class="functiontext">Calculus::Variables::renumber</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">preserving</span><span class="plain">);</span>
|
|
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=25; </span><span class="identifier">j</span><span class="plain">>=0; </span><span class="identifier">j</span><span class="plain">--)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="constant">FREE_VST</span><span class="plain">)</span>
|
|
<span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::insert_atom</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">,</span>
|
|
<span class="functiontext">Calculus::Atoms::QUANTIFIER_new</span><span class="plain">(</span><span class="identifier">exists_quantifier</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">, 0));</span>
|
|
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">prop</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::bind_existential is used in 11/sc (<a href="11-sc.html#SP1_3">§1.3</a>, <a href="11-sc.html#SP1_9">§1.9</a>, <a href="11-sc.html#SP3_7">§3.7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. Substitution. </b>In the following, we substitute term T (a constant or function) in place
|
|
of variable v in the given proposition. We begin with two utility routines
|
|
to substitute into the variable "underneath" a given term.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::substitute_v_in_term</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">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">t</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"> == </span><span class="identifier">v</span><span class="plain">) { *</span><span class="identifier">pt</span><span class="plain"> = *</span><span class="identifier">t</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</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">return</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::substitute_v_in_term</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="identifier">v</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::substitute_nothing_in_term</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">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">pt</span><span class="plain">-</span><span class="element">>constant</span><span class="plain">) && (</span><span class="functiontext">Rvalues::is_nothing_object_constant</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">pt</span><span class="plain"> = *</span><span class="identifier">t</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">pt</span><span class="plain">-</span><span class="element">>function</span><span class="plain">) </span><span class="functiontext">Calculus::Variables::substitute_nothing_in_term</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="identifier">t</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::substitute_term_in_term</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">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">pt</span><span class="plain">-</span><span class="element">>constant</span><span class="plain">) { *</span><span class="identifier">pt</span><span class="plain"> = *</span><span class="identifier">t</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">pt</span><span class="plain">-</span><span class="element">>function</span><span class="plain">) </span><span class="functiontext">Calculus::Variables::substitute_term_in_term</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="identifier">t</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::substitute_v_in_term is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::substitute_nothing_in_term is used in 11/sm (<a href="11-sm.html#SP3_2">§3.2</a>).</p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::substitute_term_in_term is used in 11/sm (<a href="11-sm.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>Now the main procedure. This is one of those deceptive problems where the
|
|
actual algorithm is obvious, but the circumstances when it can validly be
|
|
applied are less so.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The difficulty depends on the term T being substituted in for the variable
|
|
v. In general every term is a chain of functions with, right at the end,
|
|
either a constant or a variable. If a constant is underneath, there is no
|
|
problem at all. But if there is a variable underneath T — a VUT, as we
|
|
say below — then it's possible that the substitution introduces circularities
|
|
which would make it invalid. If that happens, we run into this:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">DISALLOW</span><span class="plain">(</span><span class="identifier">msg</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verify_only</span><span class="plain">) { *</span><span class="identifier">allowed</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">prop</span><span class="plain">; }</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="identifier">msg</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. </b>So the routine is intended to be called twice: once to ask if the situation
|
|
looks viable, and once to perform the substitution itself.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Calculus::Variables::substitute_term</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</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">t</span><span class="plain">,</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">verify_only</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">allowed</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">changed</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verify_only</span><span class="plain">) *</span><span class="identifier">allowed</span><span class="plain"> = </span><span class="identifier">TRUE</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">DISALLOW</span><span class="plain">(</span><span class="string">"variable substitution out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::is_well_formed</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">DISALLOW</span><span class="plain">(</span><span class="string">"substituting into malformed prop"</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Make sure the substitution would not fail because of a circularity</span> <span class="cwebmacronumber">15.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verify_only</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">prop</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS_WORKINGS</span><span class="plain">, </span><span class="string">"Substituting %c = $0 in: $D\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">], &</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::substitute_v_in_term</span><span class="plain">(&(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]), </span><span class="identifier">v</span><span class="plain">, &</span><span class="identifier">t</span><span class="plain">))</span>
|
|
<span class="plain">*</span><span class="identifier">changed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::is_well_formed</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"substitution made malformed prop"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">prop</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::substitute_term is used in <a href="#SP17">§17</a>, 11/sm (<a href="11-sm.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_1"></a><b>§15.1. </b>The problem we might find, then, is that setting v=T will be circular
|
|
because T itself depends on v. There are two ways this can happen: first,
|
|
T might be directly a function of v itself, i.e., the VUT might be v;
|
|
second, T might be a function of some variable w which, by being quantified
|
|
after v, is allowed to depend on it, in some way that we can't determine.
|
|
(For examples of this, see "Simplifications".)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The general rule, then, is that T can contain only constants or variables
|
|
which are free within and after the scope of v. (If w is bound
|
|
outside the scope of v but after it, this means w didn't exist at the
|
|
time that v did, and the attempted substitution would produce a proposition
|
|
which isn't well-formed — w would occur before its quantifier.) We can
|
|
check this condition pretty easily, it turns out:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Make sure the substitution would not fail because of a circularity</span> <span class="cwebmacronumber">15.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">verify_only</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) && (</span><span class="functiontext">Calculus::Variables::status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">v</span><span class="plain">) == </span><span class="constant">BOUND_VST</span><span class="plain">))</span>
|
|
<span class="identifier">DISALLOW</span><span class="plain">(</span><span class="string">"substituting bound variable"</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">vut</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="reserved">if</span><span class="plain"> (</span><span class="identifier">vut</span><span class="plain"> >= 0) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">v_has_been_seen</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">v</span><span class="plain"> == </span><span class="identifier">vut</span><span class="plain">) </span><span class="identifier">DISALLOW</span><span class="plain">(</span><span class="string">"resubstituting same variable"</span><span class="plain">);</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">v_has_been_seen</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Terms::variable_underlying</span><span class="plain">(&(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) == </span><span class="identifier">v</span><span class="plain">)</span>
|
|
<span class="identifier">v_has_been_seen</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain"> == </span><span class="constant">QUANTIFIER_ATOM</span><span class="plain">) && (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[0]</span><span class="element">.variable</span><span class="plain"> == </span><span class="identifier">vut</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">v_has_been_seen</span><span class="plain">))</span>
|
|
<span class="identifier">DISALLOW</span><span class="plain">(</span><span class="string">"substituted value may be circular"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. A footnote on variable 0. </b>Because of the special status of x (variable 0) — the one allowed to be
|
|
free in SN-propositions — we sometimes need to know about it. The range
|
|
of a bound variable can be found by looking at its quantifier, but a free
|
|
variable can remain ambiguous. The presence of a <code class="display"><span class="extract">KIND</span></code> atom will explicitly
|
|
solve the problem for us; if we don't find one, though, we will simply have
|
|
to assume that the set of objects is the domain of x. (We return <code class="display"><span class="extract">NULL</span></code>
|
|
here, but that's the assumption which the caller will have to make.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Calculus::Variables::kind_of_variable_0</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain"> == </span><span class="constant">KIND_ATOM</span><span class="plain">) && (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[0]</span><span class="element">.variable</span><span class="plain"> == 0)) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">>assert_kind</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</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::Variables::kind_of_variable_0 is used in 9/rpt (<a href="9-rpt.html#SP1">§1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b>And a quick way to substitute it:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Calculus::Variables::substitute_var_0_in</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</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="reserved">int</span><span class="plain"> </span><span class="identifier">bogus</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::substitute_term</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, 0, </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, &</span><span class="identifier">bogus</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::substitute_var_0_in is used in 12/dtd (<a href="12-dtd.html#SP7">§7</a>, <a href="12-dtd.html#SP21">§21</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b>If we are willing to work a little harder:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Calculus::Variables::infer_kind_of_variable_0</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain"> == </span><span class="constant">KIND_ATOM</span><span class="plain">) && (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[0]</span><span class="element">.variable</span><span class="plain"> == 0)) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">>assert_kind</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>element</span><span class="plain"> == </span><span class="constant">PREDICATE_ATOM</span><span class="plain">) && (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>arity</span><span class="plain"> == 1) && (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[0]</span><span class="element">.variable</span><span class="plain"> == 0)) {</span>
|
|
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">tr</span><span class="plain"> = </span><span class="identifier">RETRIEVE_POINTER_adjective_usage</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>predicate</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">adjective_meaning</span><span class="plain"> *</span><span class="identifier">am</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::first_meaning</span><span class="plain">(</span><span class="identifier">aph</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="functiontext">Adjectives::Meanings::get_domain</span><span class="plain">(</span><span class="identifier">am</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</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::Variables::infer_kind_of_variable_0 is used in 14/rv (<a href="14-rv.html#SP18">§18</a>), 14/ds (<a href="14-ds.html#SP3">§3</a>, <a href="14-ds.html#SP6">§6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. Detect locals. </b>Properly speaking, this has nothing to do with variables,
|
|
but it solves a similar problem.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Here we search a proposition to look for any term involving a local variable.
|
|
This is used to verify past tense propositions, which cannot rely on local
|
|
values because their contents may have been wiped and reused many times
|
|
since the time with which the proposition is concerned.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::detect_locals</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">example</span><span class="plain">) {</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">locals_count</span><span class="plain"> = 0;</span>
|
|
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">>arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="identifier">locals_count</span><span class="plain"> =</span>
|
|
<span class="functiontext">Calculus::Variables::detect_local_in_term</span><span class="plain">(&(</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">>terms</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]), </span><span class="identifier">locals_count</span><span class="plain">, </span><span class="identifier">example</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">locals_count</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::detect_local_in_term</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">int</span><span class="plain"> </span><span class="identifier">locals_count</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">example</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="identifier">locals_count</span><span class="plain"> += </span><span class="functiontext">Calculus::Variables::detect_local_in_term</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="identifier">locals_count</span><span class="plain">, </span><span class="identifier">example</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">locals_count</span><span class="plain"> += </span><span class="functiontext">Calculus::Variables::detect_local_in_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="identifier">locals_count</span><span class="plain">, </span><span class="identifier">example</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">locals_count</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Variables::detect_local_in_spec</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="reserved">int</span><span class="plain"> </span><span class="identifier">locals_count</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">example</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</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">locals_count</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="constant">LOCAL_VARIABLE_NT</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">example</span><span class="plain">) && (*</span><span class="identifier">example</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) *</span><span class="identifier">example</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="identifier">locals_count</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">) {</span>
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</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">NonlocalVariables::is_global</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">example</span><span class="plain">) && (*</span><span class="identifier">example</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) *</span><span class="identifier">example</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="identifier">locals_count</span><span class="plain">;</span>
|
|
<span class="plain">}</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">spec</span><span class="plain">)) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">param</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_THROUGH_TOKENS_PARSED_IN_INV</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">param</span><span class="plain">)</span>
|
|
<span class="identifier">locals_count</span><span class="plain"> +=</span>
|
|
<span class="functiontext">Calculus::Variables::detect_local_in_spec</span><span class="plain">(</span><span class="identifier">param</span><span class="plain">, </span><span class="identifier">locals_count</span><span class="plain">, </span><span class="identifier">example</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">-</span><span class="element">>down</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="identifier">locals_count</span><span class="plain"> +=</span>
|
|
<span class="functiontext">Calculus::Variables::detect_local_in_spec</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">locals_count</span><span class="plain">, </span><span class="identifier">example</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">locals_count</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::detect_locals is used in 10/varc (<a href="10-varc.html#SP13_3">§13.3</a>), 12/dtd (<a href="12-dtd.html#SP13">§13</a>).</p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::detect_local_in_term appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Calculus::Variables::detect_local_in_spec appears nowhere else.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="11-pr.html">Back to 'Propositions'</a></li><li><a href="11-tc.html">Continue with 'Tree Conversions'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|