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

1633 lines
212 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>12/ca</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 '12/dtd' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#12">Chapter 12: Use of Propositions</a></li><li><b>Deciding to Defer</b></li></ul><p class="purpose">To decide whether a proposition can be compiled immediately, in the body of the current routine, or whether it must be deferred to a routine of its own, which is called from the current routine.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP3">&#167;3. The guillotine</a></li><li><a href="#SP4">&#167;4. Deferral requests</a></li><li><a href="#SP7">&#167;7. Testing, or deferring a test</a></li><li><a href="#SP11">&#167;11. Forcing with now, or deferring the force</a></li><li><a href="#SP12">&#167;12. Multipurpose descriptions</a></li><li><a href="#SP23">&#167;23. Domains of loops</a></li><li><a href="#SP28">&#167;28. Checking the validity of a description</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>So far in this chapter, we have written code which suggests that there
are basically only three ways to compile a proposition: as a test
("if the tree is blossoming"), as code forcing it to be true ("now
the tree is blossoming") or as code forcing it to be false ("now the
tree is not blossoming"). That's not quite true, and so deferral can happen
for a number of different reasons, enumerated as follows:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">CONDITION_DEFER</span><span class="plain"> 1 </span> <span class="comment">"if S", where S is a sentence</span>
<span class="definitionkeyword">define</span> <span class="constant">NOW_ASSERTION_DEFER</span><span class="plain"> 2 </span> <span class="comment">"now S"</span>
<span class="definitionkeyword">define</span> <span class="constant">EXTREMAL_DEFER</span><span class="plain"> 3 </span> <span class="comment">"the heaviest X", where X is a description</span>
<span class="definitionkeyword">define</span> <span class="constant">LOOP_DOMAIN_DEFER</span><span class="plain"> 4 </span> <span class="comment">"repeat with I running through X"</span>
<span class="definitionkeyword">define</span> <span class="constant">NUMBER_OF_DEFER</span><span class="plain"> 5 </span> <span class="comment">"the number of X"</span>
<span class="definitionkeyword">define</span> <span class="constant">TOTAL_DEFER</span><span class="plain"> 6 </span> <span class="comment">"the total P of X"</span>
<span class="definitionkeyword">define</span> <span class="constant">RANDOM_OF_DEFER</span><span class="plain"> 7 </span> <span class="comment">"a random X"</span>
<span class="definitionkeyword">define</span> <span class="constant">LIST_OF_DEFER</span><span class="plain"> 8 </span> <span class="comment">"the list of X"</span>
<span class="definitionkeyword">define</span> <span class="constant">MULTIPURPOSE_DEFER</span><span class="plain"> 100 </span> <span class="comment">potentially any of the above</span>
</pre>
<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_prop_deferral</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">reason</span><span class="plain">; </span> <span class="comment">what we intend to do with it: one of the reasons above</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">proposition_to_defer</span><span class="plain">; </span> <span class="comment">the proposition</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">deferred_from</span><span class="plain">; </span> <span class="comment">remember where it came from, for Problem reports</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">defn_ref</span><span class="plain">; </span> <span class="comment">sometimes we must remember other things too</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">cinder_kinds</span><span class="plain">[16]; </span> <span class="comment">the kinds of value being cindered (see below)</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">ppd_package</span><span class="plain">; </span> <span class="comment">where to put both of the following:</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ppd_iname</span><span class="plain">; </span> <span class="comment">routine to implement this</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">rtp_iname</span><span class="plain">; </span> <span class="comment">compile a string of the origin text for run-time problems?</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">pcalc_prop_deferral</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure pcalc_prop_deferral is accessed in 12/cad, 12/cdp and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The guillotine. </b>We must be careful not to request a fresh deferral after the point at which
all deferral requests are redeemed &mdash; they would then never be reached.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_further_deferrals</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::allow_no_further_deferrals</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">no_further_deferrals</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::Deferrals::allow_no_further_deferrals is used in 1/mr (<a href="1-mr.html#SP4_14">&#167;4.14</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Deferral requests. </b>The following fills out the paperwork to request a deferred proposition.
</p>
<pre class="display">
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</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">reason</span><span class="plain">) {</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">pcalc_prop_deferral</span><span class="plain">);</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;proposition_to_defer</span><span class="plain"> = </span><span class="identifier">prop</span><span class="plain">;</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;reason</span><span class="plain"> = </span><span class="identifier">reason</span><span class="plain">;</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;deferred_from</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;rtp_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_package</span><span class="plain"> = </span><span class="functiontext">Hierarchy::package_in_enclosure</span><span class="plain">(</span><span class="constant">PROPOSITIONS_HAP</span><span class="plain">);</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">PROPOSITION_HL</span><span class="plain">, </span><span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_package</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_further_deferrals</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Too late now to defer propositions"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::new_deferred_proposition is used in <a href="#SP5">&#167;5</a>, <a href="#SP6">&#167;6</a>, <a href="#SP7_1">&#167;7.1</a>, <a href="#SP11">&#167;11</a>, <a href="#SP13">&#167;13</a>, <a href="#SP16">&#167;16</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>It's worth cacheing deferral requests in the case of loop domains,
because they are typically needed in the case of repeat-through loops where
the same proposition is used three times in a row.
</p>
<pre class="display">
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">cache_loop_proposition</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">cache_loop_pdef</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="functiontext">Calculus::Deferrals::defer_loop_domain</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_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prop</span><span class="plain"> == </span><span class="identifier">cache_loop_proposition</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">cache_loop_pdef</span><span class="plain">;</span>
<span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">LOOP_DOMAIN_DEFER</span><span class="plain">);</span>
<span class="identifier">cache_loop_proposition</span><span class="plain"> = </span><span class="identifier">prop</span><span class="plain">;</span>
<span class="identifier">cache_loop_pdef</span><span class="plain"> = </span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::defer_loop_domain is used in <a href="#SP26">&#167;26</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The following shorthand routine takes a description SP, converts it to
a proposition φ(x), then defers this and returns the number <code class="display"><span class="extract">n</span></code> such
that the resulting routine will be called <code class="display"><span class="extract">Prop_n</span></code>.
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Calculus::Deferrals::compile_deferred_description_test</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">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Specifications::to_proposition</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">Calculus::Propositions::contains_callings</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantCallDeferredDescs</span><span class="plain">),</span>
<span class="string">"'called' can't be used when testing a description"</span><span class="plain">,</span>
<span class="string">"since it would make a name for something which existed only "</span>
<span class="string">"so temporarily that it couldn't be used anywhere else."</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">else</span><span class="plain"> {</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">CONDITION_DEFER</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::compile_deferred_description_test is used in 21/ac (<a href="21-ac.html#SP14">&#167;14</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Testing, or deferring a test. </b>Given a proposition φ, and a value v, we compile a valid I6 condition
to decide whether or not φ(v) is true. φ can either be a sentence
with all variables bound, in which case v must be null, or can have just
variable x free, in which case v must not be null.
</p>
<p class="inwebparagraph">We defer the proposition to a routine of its own if and only if it contains
quantification.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_test_of_proposition</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">substitution</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">value_holster</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::compile_test_of_proposition_inner</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">substitution</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::compile_test_of_proposition_inner</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">,</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">substitution</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">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS_WORKINGS</span><span class="plain">, </span><span class="string">"Compiling as test: $D\</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">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::copy</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">prop</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</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">Calculus::Propositions::contains_quantifier</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Defer test of proposition instead</span> <span class="cwebmacronumber">7.1</span>&gt;<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">substitution</span><span class="plain">) </span><span class="functiontext">Calculus::Variables::substitute_var_0_in</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">substitution</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">pcalc_prop</span><span class="plain"> *</span><span class="identifier">last_pl</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</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="identifier">last_pl</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_pl</span><span class="plain">) </span><span class="functiontext">Calculus::Deferrals::ctop_recurse</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">last_pl</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_test_of_proposition is used in <a href="#SP10">&#167;10</a>, <a href="#SP20">&#167;20</a>, <a href="#SP23">&#167;23</a>, 14/cn (<a href="14-cn.html#SP16">&#167;16</a>), 15/ma (<a href="15-ma.html#SP13">&#167;13</a>), 25/ci (<a href="25-ci.html#SP3_2_3_4_1_1_1">&#167;3.2.3.4.1.1.1</a>), 25/cp (<a href="25-cp.html#SP5_3_5_3">&#167;5.3.5.3</a>).</p>
<p class="endnote">The function Calculus::Deferrals::compile_test_of_proposition_inner appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>Since this is the first of our deferrals, let's take it slowly. We are
compiling code in some outer routine &mdash; let's call it <code class="display"><span class="extract">R</span></code> &mdash; and the idea
is to compile a function call <code class="display"><span class="extract">Prop_19(...)</span></code> into <code class="display"><span class="extract">R</span></code> where the test should
be; this function will return either <code class="display"><span class="extract">true</span></code> or <code class="display"><span class="extract">false</span></code>, and its job is to
test the proposition for us. (Deferred propositions are numbered in order
of deferral; for the sake of example, we'll suppose ours in number 19.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Defer test of proposition instead</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="functiontext">LocalVariables::begin_condition_emit</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">go_up</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">If the proposition is a negation, take care of that now</span> <span class="cwebmacronumber">7.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NC</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::count_callings_in_condition</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">NC</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">CONDITION_DEFER</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Compile the call to the test-proposition routine</span> <span class="cwebmacronumber">7.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NC</span><span class="plain"> &gt; 0) </span><span class="functiontext">Calculus::Deferrals::emit_retrieve_callings_in_condition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">NC</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NC</span><span class="plain"> &gt; 0) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">go_up</span><span class="plain">) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">LocalVariables::end_condition_emit</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_1_1"></a><b>&#167;7.1.1. </b>This is done purely for the sake of compiling tidier code: if φ = ¬(ψ)
then we defer ψ instead, negating the result of testing it.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">If the proposition is a negation, take care of that now</span> <span class="cwebmacronumber">7.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::is_a_group</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">)) {</span>
<span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::remove_topmost_group</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">NOT_BIP</span><span class="plain">); </span><span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">go_up</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">This code is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<p class="inwebparagraph"><a id="SP7_1_2"></a><b>&#167;7.1.2. </b>All of the subtlety here is to do with the fact that <code class="display"><span class="extract">R</span></code> and <code class="display"><span class="extract">Prop_19</span></code>
have access to different values &mdash; in particular, they have different sets
of local variables.
</p>
<p class="inwebparagraph">Because code in <code class="display"><span class="extract">Prop_19</span></code> cannot see the local variables of <code class="display"><span class="extract">R</span></code>, any such
values needed must be passed from <code class="display"><span class="extract">R</span></code> to <code class="display"><span class="extract">Prop_19</span></code> as call parameters.
These passed values are called "cinders".
</p>
<p class="inwebparagraph">In addition, <code class="display"><span class="extract">R</span></code> might not be able to evaluate the substitution value v
for itself, so that must also be a call parameter. It will then become the
initial value of the local variable <code class="display"><span class="extract">x</span></code> in <code class="display"><span class="extract">Prop_19</span></code>, and since x is free
in the proposition, <code class="display"><span class="extract">x</span></code> never changes in <code class="display"><span class="extract">Prop_19</span></code>: thus we effect a
substitution of x=v.
</p>
<p class="inwebparagraph">For example, <code class="display"><span class="extract">R</span></code> might contain the function call:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Prop_19(t_6, t_2, O13_sphinx)</span>
</pre>
<p class="inwebparagraph">and the function header of <code class="display"><span class="extract">Prop_19</span></code> might then look like so:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">[ Prop_19 const_0 const_1 x;</span>
</pre>
<p class="inwebparagraph">The value of <code class="display"><span class="extract">cinder_count</span></code> would then be 2.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile the call to the test-proposition routine</span> <span class="cwebmacronumber">7.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::Cinders::find_emit</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pdef</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">substitution</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">substitution</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::ctop_recurse</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</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">from_pl</span><span class="plain">, </span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">to_pl</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">active</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">bl</span><span class="plain"> = 0;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">penultimate_pl</span><span class="plain"> = </span><span class="identifier">NULL</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="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">if</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> == </span><span class="identifier">from_pl</span><span class="plain">) </span><span class="identifier">active</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">active</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">bl</span><span class="plain"> == 0) &amp;&amp; (</span><span class="identifier">pl</span><span class="plain"> != </span><span class="identifier">from_pl</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Calculus::Propositions::implied_conjunction_between</span><span class="plain">(</span><span class="identifier">pl_prev</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">))) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">); </span><span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::ctop_recurse</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">from_pl</span><span class="plain">, </span><span class="identifier">pl_prev</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::ctop_recurse</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">to_pl</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain"> == </span><span class="constant">NEGATION_CLOSE_ATOM</span><span class="plain">) </span><span class="identifier">bl</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain"> == </span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">) </span><span class="identifier">bl</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> == </span><span class="identifier">to_pl</span><span class="plain">) { </span><span class="identifier">active</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">penultimate_pl</span><span class="plain"> = </span><span class="identifier">pl_prev</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">from_pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain"> == </span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">) &amp;&amp; (</span><span class="identifier">to_pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain"> == </span><span class="constant">NEGATION_CLOSE_ATOM</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">NOT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from_pl</span><span class="plain"> == </span><span class="identifier">penultimate_pl</span><span class="plain">) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Deferrals::ctop_recurse</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">from_pl</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="identifier">penultimate_pl</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">active</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</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">if</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> == </span><span class="identifier">from_pl</span><span class="plain">) </span><span class="identifier">active</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">active</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"blundered"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NEGATION_CLOSE_ATOM</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"blundered"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="functiontext">Calculus::Atoms::Compile::compile</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="constant">TEST_ATOM_TASK</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> == </span><span class="identifier">to_pl</span><span class="plain">) </span><span class="identifier">active</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::ctop_recurse is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>When we defer a test, we make "called" more tricky to achieve. Suppose
we are compiling a condition for
</p>
<blockquote>
<p>if a woman (called the moll) has a weapon (called the gun), ...</p>
</blockquote>
<p class="inwebparagraph">This needs to set two local variables, "moll" and "gun", but those
have to be locals in <code class="display"><span class="extract">R</span></code> &mdash; they are inaccessible to <code class="display"><span class="extract">Prop_19</span></code>. Somehow,
they need to be return values, but I6 supports only a single return value
from a routine, and that needs to be either <code class="display"><span class="extract">true</span></code> or <code class="display"><span class="extract">false</span></code>. What to do?
</p>
<p class="inwebparagraph">The answer is that <code class="display"><span class="extract">Prop_19</span></code> copies these values onto a special I6 array
called the "deferred calling list". The very last thing that <code class="display"><span class="extract">Prop_19</span></code>
does before it returns is to fill in this list; the very first thing we
do on receiving that return is to extract what we want from it. (Because
no other activity takes place in between, there is no risk that some
recursive use of propositions will overwrite the list.)
</p>
<p class="inwebparagraph">For example, <code class="display"><span class="extract">R</span></code> might this time contain a call like so:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">(Prop_19() &amp;&amp; (t_2=deferred_calling_list--&gt;0, t_3=deferred_calling_list--&gt;1, true))</span>
</pre>
<p class="inwebparagraph">which safely transfers the values to locals <code class="display"><span class="extract">t_2</span></code> and <code class="display"><span class="extract">t_3</span></code> of <code class="display"><span class="extract">R</span></code>. Note
that I6 evaluates conditions joined by <code class="display"><span class="extract">&amp;&amp;</span></code> from left to right, so we
can be certain that <code class="display"><span class="extract">Prop_19</span></code> has been called and has returned before we
get to the setting of <code class="display"><span class="extract">t_2</span></code> and <code class="display"><span class="extract">t_3</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::count_callings_in_condition</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">calling_count</span><span class="plain">=0;</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</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">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CALLED_ATOM</span><span class="plain">: {</span>
<span class="identifier">calling_count</span><span class="plain">++;</span>
<span class="reserved">break</span><span class="plain">;</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">calling_count</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_retrieve_callings_in_condition</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">NC</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">calling_count</span><span class="plain"> = 0, </span><span class="identifier">downs</span><span class="plain"> = 0;</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</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">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CALLED_ATOM</span><span class="plain">: {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">local</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Find which local variable in R needs the value, creating it if necessary</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">;</span>
<span class="identifier">calling_count</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">calling_count</span><span class="plain"> &lt; </span><span class="identifier">NC</span><span class="plain">) { </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">); </span><span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">downs</span><span class="plain">++; }</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">local_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">local</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="identifier">Produce::ref_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">local_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEFERRED_CALLING_LIST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">calling_count</span><span class="plain"> - 1));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">LocalVariables::add_calling_to_condition</span><span class="plain">(</span><span class="identifier">local</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> &gt; 0) { </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">downs</span><span class="plain">--; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">calling_count</span><span class="plain"> == 0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"called improperly"</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_retrieve_callings</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">calling_count</span><span class="plain">=0;</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</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">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CALLED_ATOM</span><span class="plain">: {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">local</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Find which local variable in R needs the value, creating it if necessary</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">local_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">local</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="identifier">Produce::ref_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">local_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEFERRED_CALLING_LIST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">calling_count</span><span class="plain">++);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">calling_count</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEFERRED_CALLING_LIST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 26);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::count_callings_in_condition is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<p class="endnote">The function Calculus::Deferrals::emit_retrieve_callings_in_condition is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<p class="endnote">The function Calculus::Deferrals::emit_retrieve_callings is used in <a href="#SP16">&#167;16</a>.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>And for value context:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::prepare_to_retrieve_callings</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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">condition_context</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">condition_context</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Calculus::Propositions::contains_callings</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">))) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"deferred_calling_list--&gt;26 = "</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_prepare_to_retrieve_callings</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">condition_context</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">condition_context</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Calculus::Propositions::contains_callings</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">))) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUPREF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEFERRED_CALLING_LIST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 26);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</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>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::prepare_to_retrieve_callings appears nowhere else.</p>
<p class="endnote">The function Calculus::Deferrals::emit_prepare_to_retrieve_callings is used in <a href="#SP16">&#167;16</a>.</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b><code class="display"><span class="extract">LocalVariables::ensure_called_local</span></code> is so called because it ensures that a local of the
right name and kind of value exists in <code class="display"><span class="extract">R</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Find which local variable in R needs the value, creating it if necessary</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::CALLED_get_name</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="identifier">local</span><span class="plain"> = </span><span class="functiontext">LocalVariables::ensure_called_local</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;assert_kind</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a> (twice).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>The following wrapper contributes almost nothing, but it checks some
consistency assertions and writes to the debugging log.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_test_if_var_matches_description</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">matches</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">matches</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">"VMD against null description"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">var</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">"VMD on null variable"</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">var</span><span class="plain">) != </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">) != </span><span class="constant">LOCAL_VARIABLE_NT</span><span class="plain">))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"VMD on non-variable"</span><span class="plain">);</span>
<span class="identifier">LOG_INDENT</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="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">matches</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">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">);</span>
<span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span>
<span class="functiontext">Calculus::Atoms::KIND_new</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(0)), </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">DESCRIPTION_COMPILATION</span><span class="plain">, </span><span class="string">"[VMD: $P ($u) matches $D]\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">K</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::Propositions::Checker::type_check</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="functiontext">Calculus::Propositions::Checker::tc_no_problem_reporting</span><span class="plain">()) == </span><span class="identifier">NEVER_MATCH</span><span class="plain">) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Deferrals::emit_test_of_proposition</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">LOG_OUTDENT</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_test_if_var_matches_description is used in 25/ci (<a href="25-ci.html#SP3_2_3_4_1_1_1">&#167;3.2.3.4.1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Forcing with now, or deferring the force. </b>For example, compiling code to achieve something like:
</p>
<blockquote>
<p>now the Marble Door is closed;</p>
</blockquote>
<p class="inwebparagraph">(which does not need to be deferred) or
</p>
<blockquote>
<p>now all the women are in the Dining Room;</p>
</blockquote>
<p class="inwebparagraph">(which does, since it contains a quantifier).
</p>
<p class="inwebparagraph">This is simpler than testing, because a "now" does not have callings, and
because it always acts on whole sentences &mdash; no substitution is ever needed;
the only call parameters for our <code class="display"><span class="extract">Prop_19</span></code> are the cinders, if any; and we
never need to extract from the <code class="display"><span class="extract">deferred_calling_list</span></code>.
</p>
<p class="inwebparagraph">Once again the question arises of how to force ¬(φ∧ψ) to
be true. It would be sufficient to falsify either one of φ or ψ
alone, but for the sake of symmetry we falsify both. (We took the same
decision when asserting propositions about the initial state of the model.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_now_proposition</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">quantifier_count</span><span class="plain"> = 0;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS_WORKINGS</span><span class="plain">, </span><span class="string">"Compiling as 'now': $D\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Count quantifiers in, and generally vet, the proposition to be forced</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">quantifier_count</span><span class="plain"> &gt; 0) {</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">NOW_ASSERTION_DEFER</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::Cinders::find_emit</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pdef</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">parity</span><span class="plain"> = </span><span class="identifier">TRUE</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="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">switch</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">: </span><span class="reserved">case</span><span class="plain"> </span><span class="constant">NEGATION_CLOSE_ATOM</span><span class="plain">:</span>
<span class="identifier">parity</span><span class="plain"> = (</span><span class="identifier">parity</span><span class="plain">)?</span><span class="identifier">FALSE</span><span class="plain">:</span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="functiontext">Calculus::Atoms::Compile::emit</span><span class="plain">(</span>
<span class="plain">(</span><span class="identifier">parity</span><span class="plain">)?</span><span class="constant">NOW_ATOM_TRUE_TASK</span><span class="plain">:</span><span class="constant">NOW_ATOM_FALSE_TASK</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">break</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::Deferrals::emit_now_proposition is used in <a href="#SP21">&#167;21</a>, 25/cp (<a href="25-cp.html#SP5_3_2">&#167;5.3.2</a>).</p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b>We reject multiple quantifiers as too much work, and ∃ x because
it would either require us to judge the x most likely to be meant &mdash; tricky &mdash;
or to create an x out of nothing, which it's too late for, since Inform
does not have run-time object or value creation.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Count quantifiers in, and generally vet, the proposition to be forced</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</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">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;element</span><span class="plain">) {</span>
<span class="reserved">case</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="functiontext">Calculus::Atoms::is_existence_quantifier</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantForceExistence</span><span class="plain">),</span>
<span class="string">"this is not explicit enough"</span><span class="plain">,</span>
<span class="string">"and should set out definite relationships between specific "</span>
<span class="string">"things, like 'now the cat is in the bag', not something "</span>
<span class="string">"more elusive like 'now the cat is carried by a woman.' "</span>
<span class="string">"(Which woman? That's the trouble.)"</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="functiontext">Calculus::Atoms::is_now_assertable_quantifier</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantForceGeneralised</span><span class="plain">),</span>
<span class="string">"this can't be made true with 'now'"</span><span class="plain">,</span>
<span class="string">"because it is too vague about what it applies to. It's fine "</span>
<span class="string">"to say 'now all the doors are open' or 'now none of the doors "</span>
<span class="string">"is open', because that clearly tells me which doors are "</span>
<span class="string">"affected; but if you write 'now six of the doors are open' "</span>
<span class="string">"or 'now almost all the doors are open', what am I to do?"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">quantifier_count</span><span class="plain">++;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CALLED_ATOM</span><span class="plain">:</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantForceCalling</span><span class="plain">),</span>
<span class="string">"a 'now' is not allowed to call names"</span><span class="plain">,</span>
<span class="string">"and it wouldn't really make sense to do so anyway. 'if "</span>
<span class="string">"a person (called the victim) is in the Trap Room' makes "</span>
<span class="string">"sense, because it gives a name - 'victim' - to someone "</span>
<span class="string">"whose identity we don't know. But 'now a person (called "</span>
<span class="string">"the victim) is in the Trap Room' won't be allowed, "</span>
<span class="string">"because 'now' can only talk about people or things whose "</span>
<span class="string">"identities we do know."</span><span class="plain">);</span>
<span class="reserved">return</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="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Multipurpose descriptions. </b>Descriptions in the form φ(x), where x is free, are also sometimes
converted into values &mdash; this is the kind of value "description". The
I6 representation is (the address of) a routine <code class="display"><span class="extract">D</span></code> which, in general,
performs task u on value v when called as <code class="display"><span class="extract">D(u, v)</span></code>, where u is
expected to be one of the following values. (Note that v is only needed
in the first two cases.)
</p>
<p class="inwebparagraph">These numbers must be negative, since they need to be different from
every valid member of a quantifiable domain (objects, enumerated kinds, truth
states, times of day, and so on).
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">CONDITION_DUSAGE</span><span class="plain"> -1 </span> <span class="comment">return <code class="display"><span class="extract">true</span></code> iff φ(v)</span>
<span class="definitionkeyword">define</span> <span class="constant">LOOP_DOMAIN_DUSAGE</span><span class="plain"> -2 </span> <span class="comment">return the next x after v such that φ(x)</span>
<span class="definitionkeyword">define</span> <span class="constant">NUMBER_OF_DUSAGE</span><span class="plain"> -3 </span> <span class="comment">return the number of w such that φ(w)</span>
<span class="definitionkeyword">define</span> <span class="constant">RANDOM_OF_DUSAGE</span><span class="plain"> -4 </span> <span class="comment">return a random w such that φ(w), or 0 if none exists</span>
<span class="definitionkeyword">define</span> <span class="constant">TOTAL_DUSAGE</span><span class="plain"> -5 </span> <span class="comment">return the total value of a property among w such that φ(w)</span>
<span class="definitionkeyword">define</span> <span class="constant">EXTREMAL_DUSAGE</span><span class="plain"> -6 </span> <span class="comment">return the maximal property value among such w</span>
<span class="definitionkeyword">define</span> <span class="constant">LIST_OF_DUSAGE</span><span class="plain"> -7 </span> <span class="comment">return the list of w such that φ(w)</span>
</pre>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>Multi-purpose description routines are pretty dandy, then, but they have
one big drawback: they can't be passed cinders, because they might be called
from absolutely anywhere. Hence the following:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::compile_multiple_use_proposition</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</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">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">negate</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">quantifier</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="functiontext">Descriptions::get_quantifier</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">q</span><span class="plain"> == </span><span class="identifier">not_exists_quantifier</span><span class="plain">) </span><span class="identifier">negate</span><span class="plain"> = </span><span class="identifier">TRUE</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">q</span><span class="plain">) &amp;&amp; (</span><span class="identifier">q</span><span class="plain"> != </span><span class="identifier">for_all_quantifier</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_spec</span><span class="plain">(2, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1 you wrote the description '%2' in the context of a value, "</span>
<span class="string">"but descriptions used that way are not allowed to talk about "</span>
<span class="string">"quantities. For example, it's okay to write 'an even number' "</span>
<span class="string">"as a description value, but not 'three numbers' or 'most numbers'."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</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="functiontext">Calculus::Propositions::from_spec</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">negate</span><span class="plain">) {</span>
<span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="functiontext">Calculus::Atoms::new</span><span class="plain">(</span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">), </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="functiontext">Calculus::Atoms::new</span><span class="plain">(</span><span class="constant">NEGATION_CLOSE_ATOM</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span>
<span class="functiontext">Calculus::Atoms::KIND_new</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(0)), </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::Checker::type_check</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="functiontext">Calculus::Propositions::Checker::tc_no_problem_reporting</span><span class="plain">()) == </span><span class="identifier">NEVER_MATCH</span><span class="plain">) </span><span class="reserved">return</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">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::detect_locals</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, &amp;</span><span class="identifier">example</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Offending proposition: $D\</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">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">example</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_LocalInDescription</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but descriptions used as values are not allowed to "</span>
<span class="string">"contain references to temporary values (defined by 'let', or by loops, "</span>
<span class="string">"or existing only in certain rulebooks or actions, say) - unfortunately "</span>
<span class="string">"'%2' is just such a temporary value. The problem is that it may well "</span>
<span class="string">"not exist any more when the description needs to be used, in another "</span>
<span class="string">"time and another place."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">MULTIPURPOSE_DEFER</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</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">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::compile_multiple_use_proposition is used in 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>Because multipurpose descriptions have this big drawback, we want to avoid
them if we possibly can. Fortunately something much simpler will often do.
For example, consider:
</p>
<blockquote>
<p>[1] the number of members of S</p>
</blockquote>
<blockquote>
<p>[2] the number of closed doors</p>
</blockquote>
<p class="inwebparagraph">where S, in [1], is a description which appears as a parameter in a phrase.
In [1] we have no way of knowing what S might be, but we can safely assume
that it has been compiled as a multi-purpose description routine, and
therefore compile the function call:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">D(NUMBER_OF_DUSAGE)</span>
</pre>
<p class="inwebparagraph">But in case [2] it is sufficient to take φ(x) = door(x)∧closed(x),
defer it to a proposition with reason <code class="display"><span class="extract">NUMBER_OF_DEFER</span></code>, and then compile just
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Prop_19()</span>
</pre>
<p class="inwebparagraph">to perform the calculation. We never need a multi-purpose description routine for
φ(x) because it only occurs in this one context.
</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>We now perform this trick for "number of":
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_number_of_S</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">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">NUMBER_OF_DUSAGE</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</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="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::prop_verify_descriptive</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="string">"a number of things matching a description"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::emit_call_to_deferred_desc</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">NUMBER_OF_DEFER</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_number_of_S is used in 25/cii (<a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>Where we employ:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</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">if</span><span class="plain"> ((</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) == </span><span class="identifier">CON_description</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">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::Deferrals::emit_call_to_deferred_desc</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">reason</span><span class="plain">, </span><span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">data</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="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::new_deferred_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">reason</span><span class="plain">);</span>
<span class="identifier">pdef</span><span class="plain">-</span><span class="element">&gt;defn_ref</span><span class="plain"> = </span><span class="identifier">data</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">with_callings</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::contains_callings</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">with_callings</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">Produce::level</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::emit_prepare_to_retrieve_callings</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">int</span><span class="plain"> </span><span class="identifier">arity</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::Cinders::find_count</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pdef</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="identifier">arity</span><span class="plain"> = </span><span class="identifier">arity</span><span class="plain"> + 2;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">arity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT0_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT2_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 3: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT3_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 4: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT4_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"indirect function call with too many arguments"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::Cinders::find_emit</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pdef</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="functiontext">Frames::emit_allocation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id_as_val</span><span class="plain">(</span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Produce::level</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()) &gt; </span><span class="identifier">L</span><span class="plain">) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::emit_retrieve_callings</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">with_callings</span><span class="plain">) { </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); }</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::spec_is_variable_of_kind_description is used in <a href="#SP15">&#167;15</a>, <a href="#SP17">&#167;17</a>, <a href="#SP18">&#167;18</a>, <a href="#SP19">&#167;19</a>, <a href="#SP20">&#167;20</a>, <a href="#SP22">&#167;22</a>, <a href="#SP23">&#167;23</a>.</p>
<p class="endnote">The function Calculus::Deferrals::emit_call_to_deferred_desc is used in <a href="#SP15">&#167;15</a>, <a href="#SP17">&#167;17</a>, <a href="#SP18">&#167;18</a>, <a href="#SP19">&#167;19</a>, <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>And for "list of":
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_list_of_S</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">kind</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="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_DESC_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::emit_allocation</span><span class="plain">(</span><span class="identifier">K</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">spec</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id_as_val</span><span class="plain">(</span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</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="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::prop_verify_descriptive</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="string">"a list of things matching a description"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::emit_call_to_deferred_desc</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">LIST_OF_DEFER</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_list_of_S is used in 25/cii (<a href="25-cii.html#SP3_2_2">&#167;3.2.2</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>The pattern is repeated for "a random ...":
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_random_of_S</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">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_description</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">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">Kinds::unary_construction_material</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">) &amp;&amp; (</span><span class="identifier">Kinds::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">), </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Descriptions::to_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Descriptions::number_of_adjectives_applied_to</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == 0)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT0_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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">Kinds::Behaviour::get_ranger_iname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">return</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">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">RANDOM_OF_DUSAGE</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</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="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::prop_verify_descriptive</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="string">"a random thing matching a description"</span><span class="plain">, </span><span class="identifier">spec</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">Calculus::Propositions::describes_kind</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">K</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Behaviour::compile_domain_possible</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue random impossible problem</span> <span class="cwebmacronumber">18.1</span>&gt;
<span class="reserved">else</span>
<span class="functiontext">Calculus::Deferrals::emit_call_to_deferred_desc</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">RANDOM_OF_DEFER</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_random_of_S is used in 25/cii (<a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="inwebparagraph"><a id="SP18_1"></a><b>&#167;18.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue random impossible problem</span> <span class="cwebmacronumber">18.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RandomImpossible</span><span class="plain">),</span>
<span class="string">"this asks to find a random choice from a range which is too "</span>
<span class="string">"large or impractical"</span><span class="plain">,</span>
<span class="string">"so can't be done. For instance, 'a random person' is fine - "</span>
<span class="string">"it's clear exactly who all the people are, and the supply is "</span>
<span class="string">"limited - but not 'a random text'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>And similarly for "total of":
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_total_of_S</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="identifier">parse_node</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">prn</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">"total of on non-property"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_iname</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="functiontext">Properties::iname</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">TOTAL_DUSAGE</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</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="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::prop_verify_descriptive</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="string">"a total property value for things matching a description"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::emit_call_to_deferred_desc</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">TOTAL_DEFER</span><span class="plain">,</span>
<span class="identifier">STORE_POINTER_property</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_total_of_S is used in 25/cii (<a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>Also for the occasionally useful task of seeing if the current value of
the "substitution variable") is within the domain.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_substitution_test</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">in</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">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT2_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">CONDITION_DUSAGE</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">in</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Deferrals::emit_test_of_proposition</span><span class="plain">(</span>
<span class="identifier">in</span><span class="plain">, </span><span class="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_substitution_test is used in 25/cii (<a href="25-cii.html#SP3_5_5">&#167;3.5.5</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>A variation on which is:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_substitution_now</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">in</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">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Variables::substitute_var_0_in</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">in</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Checker::type_check</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="functiontext">Calculus::Propositions::Checker::tc_no_problem_reporting</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">save_cck</span><span class="plain"> = </span><span class="identifier">suppress_C14CantChangeKind</span><span class="plain">;</span>
<span class="identifier">suppress_C14CantChangeKind</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext">Calculus::Deferrals::emit_now_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">suppress_C14CantChangeKind</span><span class="plain"> = </span><span class="identifier">save_cck</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_substitution_now is used in 25/cii (<a href="25-cii.html#SP3_5_6">&#167;3.5.6</a>).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>And the extremal case is pretty well the same, too, with only some fuss
over identifying which superlative is meant. We get here from code like
</p>
<blockquote>
<p>let X be the heaviest thing in the wooden box;</p>
</blockquote>
<p class="inwebparagraph">where there has previously been a definition of "heavy".
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_extremal_of_S</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">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sign</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="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"extremal of on non-property"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_iname</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="functiontext">Properties::iname</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">PROPERTY_LOOP_SIGN_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">sign</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">EXTREMAL_DUSAGE</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">measurement_definition</span><span class="plain"> *</span><span class="identifier">mdef_found</span><span class="plain"> = </span><span class="functiontext">Properties::Measurement::retrieve</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">sign</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mdef_found</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="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::prop_verify_descriptive</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="string">"an extreme case of something matching a description"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::emit_call_to_deferred_desc</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="constant">EXTREMAL_DEFER</span><span class="plain">,</span>
<span class="identifier">STORE_POINTER_measurement_definition</span><span class="plain">(</span><span class="identifier">mdef_found</span><span class="plain">), </span><span class="identifier">NULL</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::Deferrals::emit_extremal_of_S is used in 25/cii (<a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Domains of loops. </b>Here we define an I6 <code class="display"><span class="extract">for</span></code> loop header to handle a repeat loop through all
of the x matching a given description φ(x).
</p>
<p class="inwebparagraph">We are allowed to use two local variables in the current stack frame: <code class="display"><span class="extract">t_v1</span></code>
and <code class="display"><span class="extract">t_v2</span></code>, where the numbers v_1 and v_2 are supplied to us. We mark
them as available for reuse once the loop has been exited, by setting their
scope to the code block for the loop.
</p>
<p class="inwebparagraph">We use v_1 as the current value and v_2 as the one which will follow it.
Always evaluating one step ahead protects us in case the body of the loop
takes action which moves v_1 out of the domain &mdash; e.g., in the case of
</p>
<blockquote>
<p>repeat with T running through items on the table: now T is in the box.</p>
</blockquote>
<p class="inwebparagraph">This is the famous "broken <code class="display"><span class="extract">objectloop</span></code>" hazard of Inform 6, which typically
occurs because the mechanism to move from one value to the next uses <code class="display"><span class="extract">sibling</span></code>
in the I6 object tree, and that relies on v_1 being an object which is still
in the same location at the end of the loop as at the beginning.
</p>
<p class="inwebparagraph">Thus a typical loop header has the form
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">for (t_1=D(0), t_2=D(t_1): t_1: t_1=t_2, t_2=D(t_1))</span>
</pre>
<p class="inwebparagraph">where <code class="display"><span class="extract">D</span></code> is a routine such that at 0 it produces the first element of the
domain, and then given <code class="display"><span class="extract">x</span></code> in the domain, <code class="display"><span class="extract">D(x)</span></code> produces the next element
until it returns 0, when the domain is exhausted.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_repeat_through_domain_S</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">local_variable</span><span class="plain"> *</span><span class="identifier">v1</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">DK</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</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">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">DK</span><span class="plain">) != </span><span class="identifier">CON_description</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"repeat through non-description"</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">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">DK</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v2</span><span class="plain"> = </span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="functiontext">Frames::Blocks::set_scope_to_block_about_to_open</span><span class="plain">(</span><span class="identifier">v1</span><span class="plain">);</span>
<span class="functiontext">Frames::Blocks::set_scope_to_block_about_to_open</span><span class="plain">(</span><span class="identifier">v2</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">val_var_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">aux_var_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v2</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">domain_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">use_as_is</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="functiontext">Calculus::Deferrals::spec_is_variable_of_kind_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="identifier">use_as_is</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">domain_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::from_spec</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">Calculus::Propositions::contains_callings</span><span class="plain">(</span><span class="identifier">domain_prop</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue called in repeat problem</span> <span class="cwebmacronumber">23.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">FOR_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">val_var_s</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_as_is</span><span class="plain">) </span><span class="functiontext">Calculus::Deferrals::emit_repeat_call</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">else</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_repeat_domain</span><span class="plain">(</span><span class="identifier">domain_prop</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">aux_var_s</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_as_is</span><span class="plain">) </span><span class="functiontext">Calculus::Deferrals::emit_repeat_call</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_repeat_domain</span><span class="plain">(</span><span class="identifier">domain_prop</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">val_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">val_var_s</span><span class="plain">);</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">aux_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">aux_var_s</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_as_is</span><span class="plain">) </span><span class="functiontext">Calculus::Deferrals::emit_repeat_call</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_repeat_domain</span><span class="plain">(</span><span class="identifier">domain_prop</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="reserved">i6_schema</span><span class="plain"> </span><span class="identifier">loop_schema</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::write_loop_schema</span><span class="plain">(&amp;</span><span class="identifier">loop_schema</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(&amp;</span><span class="identifier">loop_schema</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">v2</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="functiontext">ParseTreeUsage::is_lvalue</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::emit_test_of_proposition</span><span class="plain">(</span>
<span class="functiontext">Lvalues::new_LOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">),</span>
<span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT2_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">CONDITION_DUSAGE</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="functiontext">Lvalues::new_LOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue bad repeat domain problem</span> <span class="cwebmacronumber">23.2</span>&gt;<span class="plain">;</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_repeat_through_domain_S is used in 25/cii (<a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="inwebparagraph"><a id="SP23_1"></a><b>&#167;23.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue called in repeat problem</span> <span class="cwebmacronumber">23.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CalledInRepeat</span><span class="plain">),</span>
<span class="string">"this tries to use '(called ...)' to give names to values "</span>
<span class="string">"arising in the course of working out what to repeat through"</span><span class="plain">,</span>
<span class="string">"but this is not allowed. (Sorry: it's too hard to get right.)"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_2"></a><b>&#167;23.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue bad repeat domain problem</span> <span class="cwebmacronumber">23.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadRepeatDomain</span><span class="plain">),</span>
<span class="string">"this describes a collection of values which can't be repeated through"</span><span class="plain">,</span>
<span class="string">"because the possible range is too large (or has no sensible ordering). "</span>
<span class="string">"For instance, you can 'repeat with D running through doors' because "</span>
<span class="string">"there are only a small number of doors and they can be put in order "</span>
<span class="string">"of creation. But you can't 'repeat with N running through numbers' "</span>
<span class="string">"because numbers are without end."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>If the domain is a kind of object, say "things", then we can certainly
perform the loop by inefficiently looping through all objects and checking
each in turn for its class membership &mdash; this is slow, though, so we ask
the counting plugin to optimise matters by using a linked list fixed at
compile time.
</p>
<p class="inwebparagraph">If it happens that no instances exist &mdash; unlikely for things, but often true
of more unusual kinds &mdash; then a loop header which never executes the block
following it is compiled.
</p>
<p class="inwebparagraph">If the domain <code class="display"><span class="extract">K</span></code> is not a kind of object, then we loop through the
known constants which make up this kind of value; each kind is
allowed to provide its own loop syntax for this. For "time", for
instance, it becomes a <code class="display"><span class="extract">for</span></code> loop running from 0 (midnight) to 1439 (one
minute to midnight).
</p>
<p class="inwebparagraph">In all cases, we copy a valid schema to <code class="display"><span class="extract">sch</span></code> if the loop can be made, and
return <code class="display"><span class="extract">TRUE</span></code> or <code class="display"><span class="extract">FALSE</span></code> to indicate success.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_LOOP_DOMAIN_SCHEMA_LENGTH</span><span class="plain"> 1000</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::write_loop_schema</span><span class="plain">(</span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">sch</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="reserved">if</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">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Counting::optimise_loop</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="functiontext">Calculus::Schemas::modify</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">, </span><span class="string">"objectloop (*1 ofclass %n)"</span><span class="plain">,</span>
<span class="functiontext">Kinds::RunTime::I6_classname</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">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="functiontext">Calculus::Schemas::modify</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">, </span><span class="string">"objectloop (*1 ofclass Object)"</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>
<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="functiontext">Calculus::Schemas::modify</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">,</span>
<span class="string">"for (*1=1: *1&lt;=%d: *1++)"</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::get_highest_valid_value_as_integer</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">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;construct</span><span class="plain">-&gt;</span><span class="identifier">loop_domain_schema</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="identifier">NULL</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::Schemas::modify</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">p</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::Deferrals::write_loop_schema is used in <a href="#SP23">&#167;23</a>, 6/rlt (<a href="6-rlt.html#SP15_2_9_1">&#167;15.2.9.1</a>, <a href="6-rlt.html#SP15_2_10_1">&#167;15.2.10.1</a>, <a href="6-rlt.html#SP15_2_12_1">&#167;15.2.12.1</a>), 12/cdp (<a href="12-cdp.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>If the description D is not explicitly known &mdash; because it sits inside
a variable &mdash; then the following compiles code to call <code class="display"><span class="extract">D</span></code> in order to
calculate the next value in the domain after the one stored in <code class="display"><span class="extract">fromv</span></code>.
</p>
<p class="inwebparagraph">Here, once again, we know that D has been compiled to a general-purpose
deferred description routine, and we simply call that routine with the
<code class="display"><span class="extract">LOOP_DOMAIN_DUSAGE</span></code> task.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_repeat_call</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">local_variable</span><span class="plain"> *</span><span class="identifier">fromv</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT2_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="constant">LOOP_DOMAIN_DUSAGE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fromv</span><span class="plain">) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">fromv_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">fromv</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">fromv_s</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_repeat_call is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b>But if the description D=φ(x) is an explicitly known proposition,
then we defer it to a routine specifically tailored to loop domains &mdash; it
will never be needed for anything else.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_repeat_domain</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">local_variable</span><span class="plain"> *</span><span class="identifier">fromv</span><span class="plain">) {</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::defer_loop_domain</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">arity</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::Cinders::find_count</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pdef</span><span class="plain">) + 1;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">arity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT0_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT2_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 3: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT3_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 4: </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT4_BIP</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"indirect function call with too many arguments"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</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">pdef</span><span class="plain">-</span><span class="element">&gt;ppd_iname</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::Cinders::find_emit</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">pdef</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fromv</span><span class="plain">) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">fromv_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">fromv</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">fromv_s</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_repeat_domain is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. </b>And for looping over lists:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::emit_loop_over_list_S</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">local_variable</span><span class="plain"> *</span><span class="identifier">val_var</span><span class="plain">) {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">index_var</span><span class="plain"> = </span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">copy_var</span><span class="plain"> = </span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">K_number</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">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">CK</span><span class="plain"> = </span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pointery</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">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">CK</span><span class="plain">)) {</span>
<span class="identifier">pointery</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext">LocalVariables::mark_to_free_at_end_of_scope</span><span class="plain">(</span><span class="identifier">val_var</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Frames::Blocks::set_scope_to_block_about_to_open</span><span class="plain">(</span><span class="identifier">val_var</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">val_var</span><span class="plain">, </span><span class="identifier">CK</span><span class="plain">);</span>
<span class="functiontext">Frames::Blocks::set_scope_to_block_about_to_open</span><span class="plain">(</span><span class="identifier">index_var</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">val_var_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">val_var</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">index_var_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">index_var</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">copy_var_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">copy_var</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">FOR_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">copy_var_s</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">spec</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pointery</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">val_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUECREATE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id_as_val</span><span class="plain">(</span><span class="identifier">CK</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUECOPYAZ_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">val_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETITEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">copy_var_s</span><span class="plain">);</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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">val_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETITEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">copy_var_s</span><span class="plain">);</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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETLENGTH_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">copy_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">POSTINCREMENT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pointery</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUECOPYAZ_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">val_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETITEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">copy_var_s</span><span class="plain">);</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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_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">val_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETITEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</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">copy_var_s</span><span class="plain">);</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">index_var_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::emit_loop_over_list_S is used in 25/cii (<a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Checking the validity of a description. </b>The following utility routine checks that a proposition contains exactly
one unbound variable, producing problem messages if not, and that it
passes type-checking successfully.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::prop_verify_descriptive</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">char</span><span class="plain"> *</span><span class="identifier">billing</span><span class="plain">,</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">constructor</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">constructor</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">"description with null constructor"</span><span class="plain">);</span>
<span class="comment">best guess at the text to quote in any problem message</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">EW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">constructor</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">EW</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">constructor</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">))</span>
<span class="identifier">EW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">constructor</span><span class="plain">-</span><span class="element">&gt;down</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">"malformed proposition in description verification"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::number_free</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">N</span><span class="plain"> == 1)</span>
<span class="functiontext">Calculus::Propositions::Checker::type_check</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="functiontext">Calculus::Propositions::Checker::tc_problem_reporting</span><span class="plain">(</span><span class="identifier">EW</span><span class="plain">,</span>
<span class="string">"involve a range of objects matching a description"</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 1) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">billing</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">EW</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, you are asking for %2, but this should range over a "</span>
<span class="string">"simpler description than '%3', please - it should not include any "</span>
<span class="string">"determiners such as 'at least three', 'all' or 'most'. "</span>
<span class="string">"(The range is always taken to be all of the things matching "</span>
<span class="string">"the description.)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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">N</span><span class="plain"> &lt; 1) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">billing</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">EW</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, you are asking for %2, but '%3' looks as if it ranges "</span>
<span class="string">"over only a single specific object, not a whole collection of "</span>
<span class="string">"objects."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::prop_verify_descriptive is used in <a href="#SP15">&#167;15</a>, <a href="#SP17">&#167;17</a>, <a href="#SP18">&#167;18</a>, <a href="#SP19">&#167;19</a>, <a href="#SP22">&#167;22</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="12-ca.html">Back to 'Compile Atoms'</a></li><li><a href="12-cad.html">Continue with 'Cinders and Deferrals'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>