1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 00:24:22 +03:00
inform7/docs/imperative-module/4-cdp.html
2022-05-18 22:23:45 +01:00

2204 lines
324 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Compile Deferred Propositions</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Compile Deferred Propositions' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">imperative</a></li><li><a href="index.html#4">Chapter 4: Propositions</a></li><li><b>Compile Deferred Propositions</b></li></ul></div>
<p class="purpose">To compile the Inter functions needed to perform the tests or tasks deferred as being too difficult in their original contexts.</p>
<ul class="toc"><li><a href="4-cdp.html#SP1">&#167;1. Comment</a></li><li><a href="4-cdp.html#SP2">&#167;2. Preliminaries</a></li><li><a href="4-cdp.html#SP3_6_1_1">&#167;3.6.1.1. The Search</a></li><li><a href="4-cdp.html#SP3_6_1_4_1">&#167;3.6.1.4.1. The R-stack</a></li><li><a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2. Compiling the search</a></li><li><a href="4-cdp.html#SP3_6_1_4_2_2">&#167;3.6.1.4.2.2. Predicate runs and their negations</a></li><li><a href="4-cdp.html#SP3_6_1_4_2_6">&#167;3.6.1.4.2.6. Quantifiers and the Q-stack</a></li><li><a href="4-cdp.html#SP3_6_1_4_2_10">&#167;3.6.1.4.2.10. The C-stack</a></li><li><a href="4-cdp.html#SP3_5_3">&#167;3.5.3. Adaptations</a></li><li><a href="4-cdp.html#SP3_6_1_5">&#167;3.6.1.5. Adaptation to CONDITION</a></li><li><a href="4-cdp.html#SP3_6_1_7">&#167;3.6.1.7. Adaptation to NUMBER</a></li><li><a href="4-cdp.html#SP3_6_1_10">&#167;3.6.1.10. Adaptation to LIST</a></li><li><a href="4-cdp.html#SP3_6_1_12">&#167;3.6.1.12. Adaptation to RANDOM</a></li><li><a href="4-cdp.html#SP3_6_1_14">&#167;3.6.1.14. Adaptation to TOTAL</a></li><li><a href="4-cdp.html#SP3_6_1_18">&#167;3.6.1.18. Adaptation to EXTREMAL</a></li><li><a href="4-cdp.html#SP3_6_1_20">&#167;3.6.1.20. Adaptation to LOOP</a></li><li><a href="4-cdp.html#SP4">&#167;4. Compiling loop headers</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Comment. </b>The following compiles an Inter comment noting the reason for a deferral.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">DeferredPropositions::compile_comment_about_deferral_reason</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compile_comment_about_deferral_reason</span></span>:<br/><a href="4-cdp.html#SP3_6">&#167;3.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"True or false?"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Force this to be true via 'now':"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find the extremal x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find next x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Construct a list of x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"How many x satisfy this?"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find a total property value over all x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find a total real property value over all x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find a random x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MULTIPURPOSE_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Abstraction for set of x such that:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Unknown proposition deferral reason"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Preliminaries. </b>Propositions are deferred for diverse reasons: see <a href="4-dtd.html" class="internal">Deciding to Defer</a>. Here
we take our medicine, and actually compile those deferred propositions into
functions. This has to be done by an agent because funny things can happen
when we compile: we can create new text substitutions which create routines
which... and so on. (See <a href="../core-module/1-htc.html" class="internal">How To Compile (in core)</a>.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">DeferredPropositions::compilation_agent</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compilation_agent</span></span>:<br/>Deciding to Defer - <a href="4-dtd.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">compilation_subtask</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_pcalc_prop_deferral</span><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">data</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-cdp.html#SP3" class="function-link"><span class="function-syntax">DeferredPropositions::compile</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>The basic structure of a proposition function is the same for all of the
various reasons, but with considerable variations affecting (mainly) the
initial setup and the returned value.
</p>
<p class="commentary">Note that the unchecked array bounds of 26 are safe here because propositions
may only use 26 different variables at most (<span class="extract"><span class="extract-syntax">x</span></span>, <span class="extract"><span class="extract-syntax">y</span></span>, <span class="extract"><span class="extract-syntax">z</span></span>, <span class="extract"><span class="extract-syntax">a</span></span>, ..., <span class="extract"><span class="extract-syntax">w</span></span>). Only
in very contrived circumstances are there ever more than three quantifiers, so
this is plenty large enough:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">DeferredPropositions::compile</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compile</span></span>:<br/><a href="4-cdp.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ct_locals_problem_thrown</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">negated_quantifier_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">deferred_from</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">proposition_to_defer</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">MULTIPURPOSE_DEFER</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">CONDITION_DEFER</span><span class="plain-syntax">; </span><span class="comment-syntax"> redundant assignment to appease compilers</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reason_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[26], *</span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[26];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[26];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax">], *</span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">list_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">selection_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">strong_kind_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="constant-syntax">MULTIPURPOSE_DEFER</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">r</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">MULTIPURPOSE_DEFER</span><span class="plain-syntax">+1; </span><span class="identifier-syntax">r</span><span class="plain-syntax">++) </span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Simplify the proposition by flipping negated quantifiers, if possible</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">PREDICATE_CALCULUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling %n as deferred proposition: %d: reason %d: $D\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ppd_iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reason</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">packaging_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">save</span><span class="plain-syntax"> = </span><a href="3-fnc.html#SP2" class="function-link"><span class="function-syntax">Functions::begin</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ppd_iname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Declare the Inter local variables which will be needed by this deferral function</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6" class="named-paragraph-link"><span class="named-paragraph">Compile the code inside this deferral function</span><span class="named-paragraph-number">3.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if the table-lookup locals were needed</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if a negated quantifier was needed</span><span class="named-paragraph-number">3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-fnc.html#SP6" class="function-link"><span class="function-syntax">Functions::end</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">save</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rtp_iname</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Compile the constant origin text for run-time problem use</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b>We compile the following only in cases where it seems possible that a
run-time problem message may be needed; compiling it for every deferred
proposition would be wasteful of space in the Z-machine.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the constant origin text for run-time problem use</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">COTT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">deferred_from</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">COTT</span><span class="plain-syntax">, </span><span class="string-syntax">"%~W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">deferred_from</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">COTT</span><span class="plain-syntax">, </span><span class="string-syntax">"not sure where this came from"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Emit::text_constant</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rtp_iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">COTT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">COTT</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>&#167;3.2. </b>Just in case this hasn't already been done:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Simplify the proposition by flipping negated quantifiers, if possible</span><span class="named-paragraph-number">3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">changed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Simplifications::negated_determiners</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">changed</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">changed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">PREDICATE_CALCULUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Simplifications::negated_determiners: $D\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>&#167;3.3. </b>While unfortunate in a way, this is for the best, because a successful match
on a condition looking up a table would record the table and row in local
variables within the deferred proposition: they would then be wrong in the
calling function, where they are needed.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if the table-lookup locals were needed</span><span class="named-paragraph-number">3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::are_we_using_table_lookup</span></a><span class="plain-syntax">()) &amp;&amp; (!</span><span class="identifier-syntax">ct_locals_problem_thrown</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ct_locals_problem_thrown</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CantLookUpTableInDeferred</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"I am not able to look up table entries in this complicated condition"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which seems to involve making a potentially large number of checks in "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"rather few words (and may perhaps result from a misunderstanding such as "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"writing the name of a kind where an individual object is intended?)."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_4" class="paragraph-anchor"></a><b>&#167;3.4. </b>This looks like a horrible restriction, but in fact propositions are built
and simplified in such a way that it never bites. (Quantifiers are always
moved outside of negation where possible, and it is almost always possible.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if a negated quantifier was needed</span><span class="named-paragraph-number">3.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated_quantifier_found</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this involves a very complicated negative thought"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which I'm not able to untangle. Perhaps you could rephrase this more simply, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"or split it into more than one sentence?"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5" class="paragraph-anchor"></a><b>&#167;3.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the Inter local variables which will be needed by this deferral function</span><span class="named-paragraph-number">3.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"reason"</span><span class="plain-syntax">); </span><span class="comment-syntax"> no cinders exist here</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><a href="4-cad.html#SP5" class="function-link"><span class="function-syntax">Cinders::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">); </span><span class="comment-syntax"> no reason code needed, function does one thing</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_4" class="named-paragraph-link"><span class="named-paragraph">Declare the Inter call parameters needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_1" class="named-paragraph-link"><span class="named-paragraph">Declare locals corresponding to predicate calculus variables</span><span class="named-paragraph-number">3.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_2" class="named-paragraph-link"><span class="named-paragraph">Declare one pair of locals for each quantifier</span><span class="named-paragraph-number">3.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_3" class="named-paragraph-link"><span class="named-paragraph">Declare the Inter locals needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1" class="paragraph-anchor"></a><b>&#167;3.5.1. </b>If the proposition uses <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span>, we will define locals called <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span>
to hold their current values, and so on.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare locals corresponding to predicate calculus variables</span><span class="named-paragraph-number">3.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">var_states</span><span class="plain-syntax">[26];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Binding::determine_status</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_states</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax">&lt;26; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var_states</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] != </span><span class="identifier-syntax">UNUSED_VST</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">pcalc_vars</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">, </span><span class="string-syntax">"_ix"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">&#167;3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_2" class="paragraph-anchor"></a><b>&#167;3.5.2. </b>The first quantifier gets <span class="extract"><span class="extract-syntax">qcy_0</span></span>, <span class="extract"><span class="extract-syntax">qcn_0</span></span>; the second <span class="extract"><span class="extract-syntax">qcy_1</span></span>, <span class="extract"><span class="extract-syntax">qcn_1</span></span>;
and so on.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare one pair of locals for each quantifier</span><span class="named-paragraph-number">3.5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">DOMAIN_OPEN_ATOM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_extras</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">, </span><span class="string-syntax">"qcy_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">, </span><span class="string-syntax">"qcn_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">&#167;3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6" class="paragraph-anchor"></a><b>&#167;3.6. </b>A multipurpose function <span class="extract"><span class="extract-syntax">f(x)</span></span> has to test whether \(\phi(x)\) is true if \(x \geq 0\),
but if \(x &lt; 0\) then it will be one of the <span class="extract"><span class="extract-syntax">*_DUSAGE</span></span> values, and we switch on which
it is. Each of those switch cases contains code for one of the possibilities;
whereas for a single-purpose function, we just compile the code for that single
possibility.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the code inside this deferral function</span><span class="named-paragraph-number">3.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="constant-syntax">CONDITION_DUSAGE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SWITCH_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">safety_copy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">use</span><span class="plain-syntax"> = </span><span class="constant-syntax">EXTREMAL_DUSAGE</span><span class="plain-syntax">; </span><span class="identifier-syntax">use</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">CONDITION_DUSAGE</span><span class="plain-syntax">; </span><span class="identifier-syntax">use</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">use</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">EXTREMAL_DUSAGE</span><span class="plain-syntax">) </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">safety_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">use</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">CONDITION_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">LOOP_DOMAIN_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">LIST_OF_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">NUMBER_OF_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">RANDOM_OF_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">TOTAL_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">TOTAL_REAL_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">EXTREMAL_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">use</span><span class="plain-syntax"> == </span><span class="constant-syntax">TOTAL_REAL_DUSAGE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">TargetVMs::supports_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">()) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">CASE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">use</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="4-cdp.html#SP1" class="function-link"><span class="function-syntax">DeferredPropositions::compile_comment_about_deferral_reason</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1" class="named-paragraph-link"><span class="named-paragraph">Compile body of deferred proposition for the given reason</span><span class="named-paragraph-number">3.6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reason</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1" class="named-paragraph-link"><span class="named-paragraph">Compile body of deferred proposition for the given reason</span><span class="named-paragraph-number">3.6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1" class="paragraph-anchor"></a><b>&#167;3.6.1. </b>So from here on we compile code to handle a single function.
</p>
<p class="commentary">What these different cases have in common is that each is basically a search
of all possible values of the bound variables in the expression. There will
be some initialisation, something to do with each successfully found
combination, and eventually some winding-up code. For example, "number of..."
initialises by setting <span class="extract"><span class="extract-syntax">counter</span></span> to 0, on each success it performs <span class="extract"><span class="extract-syntax">counter++</span></span>,
and at the end of the search it performs <span class="extract"><span class="extract-syntax">return counter</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile body of deferred proposition for the given reason</span><span class="named-paragraph-number">3.6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">def_prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">def_prn_sign</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">OL</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_5" class="named-paragraph-link"><span class="named-paragraph">Initialisation before CONDITION search</span><span class="named-paragraph-number">3.6.1.5</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_18" class="named-paragraph-link"><span class="named-paragraph">Initialisation before EXTREMAL search</span><span class="named-paragraph-number">3.6.1.18</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_21" class="named-paragraph-link"><span class="named-paragraph">Initialisation before LOOP search</span><span class="named-paragraph-number">3.6.1.21</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_7" class="named-paragraph-link"><span class="named-paragraph">Initialisation before NUMBER search</span><span class="named-paragraph-number">3.6.1.7</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_10" class="named-paragraph-link"><span class="named-paragraph">Initialisation before LIST search</span><span class="named-paragraph-number">3.6.1.10</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_14" class="named-paragraph-link"><span class="named-paragraph">Initialisation before TOTAL search</span><span class="named-paragraph-number">3.6.1.14</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_15" class="named-paragraph-link"><span class="named-paragraph">Initialisation before TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.15</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_12" class="named-paragraph-link"><span class="named-paragraph">Initialisation before RANDOM search</span><span class="named-paragraph-number">3.6.1.12</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4" class="named-paragraph-link"><span class="named-paragraph">Compile code to search for valid combinations of variables</span><span class="named-paragraph-number">3.6.1.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">reason</span><span class="plain-syntax"> != </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">reason</span><span class="plain-syntax"> != </span><span class="constant-syntax">CONDITION_DEFER</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_8" class="named-paragraph-link"><span class="named-paragraph">Place next outer loop label</span><span class="named-paragraph-number">3.6.1.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">() &gt; </span><span class="identifier-syntax">OL</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_6" class="named-paragraph-link"><span class="named-paragraph">Winding-up after CONDITION search</span><span class="named-paragraph-number">3.6.1.6</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_19" class="named-paragraph-link"><span class="named-paragraph">Winding-up after EXTREMAL search</span><span class="named-paragraph-number">3.6.1.19</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_22" class="named-paragraph-link"><span class="named-paragraph">Winding-up after LOOP search</span><span class="named-paragraph-number">3.6.1.22</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_9" class="named-paragraph-link"><span class="named-paragraph">Winding-up after NUMBER search</span><span class="named-paragraph-number">3.6.1.9</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_11" class="named-paragraph-link"><span class="named-paragraph">Winding-up after LIST search</span><span class="named-paragraph-number">3.6.1.11</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_16" class="named-paragraph-link"><span class="named-paragraph">Winding-up after TOTAL search</span><span class="named-paragraph-number">3.6.1.16</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_17" class="named-paragraph-link"><span class="named-paragraph">Winding-up after TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.17</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_13" class="named-paragraph-link"><span class="named-paragraph">Winding-up after RANDOM search</span><span class="named-paragraph-number">3.6.1.13</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6">&#167;3.6</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_1" class="paragraph-anchor"></a><b>&#167;3.6.1.1. The Search. </b>We can now begin the real work. Given \(\phi\), we compile Inter code which
contains a magic position M (for "match") such that M is visited exactly
once for every combination of possible substitutions into the bound
variables such that \(\phi\) is true. For example,
$$ \exists x: {\it door}(x)\land{\it open}(x)\land \exists y: {\it room}(y)\land{\it in}(x, y) $$
might compile to code in the form:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> blah, blah, blah {</span>
<span class="plain-syntax"> M</span>
<span class="plain-syntax"> } rhubarb, rhubarb</span>
</pre>
<p class="commentary">such that execution reaches <span class="extract"><span class="extract-syntax">M</span></span> exactly once for each combination of open
door \(x\) and room \(y\) such that \(x\) is in \(y\). (Position <span class="extract"><span class="extract-syntax">M</span></span> is where we
will place the case-dependent code for what to do on a successful match.)
In the language of model theory, this is a loop over all interpretations
of the variables in which \(\phi\) is true.
</p>
<p class="commentary">The algorithm below is, so far as I know, original to Inform, and it is not
simple to prove correct, so the reader will excuse a fairly hefty amount of
commentary here.
</p>
<p class="commentary">Our basic method is to compile the proposition from left to right. If there
are \(k\) atoms in \(\phi\), then there are \(k+1\) positions between atoms,
counting the start and the end. We maintain the following:
</p>
<ul class="items"><li>&#9679; Invariant. Let \(\psi\) be any syntactically valid subproposition
of \(\phi\) (that is, a contiguous sequence of atoms from \(\psi\) which would
be a valid proposition in its own right). Then there are before and after
positions <span class="extract"><span class="extract-syntax">B</span></span> and <span class="extract"><span class="extract-syntax">A</span></span> in the compiled Inter code for searching \(\phi\) such that
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">A</span></span> cannot be reached except from <span class="extract"><span class="extract-syntax">B</span></span>, and
</li><li>(b) at execution time, on every occasion <span class="extract"><span class="extract-syntax">B</span></span> is reached, <span class="extract"><span class="extract-syntax">A</span></span> is then reached
exactly once for each combination of possible substitutions into the
\(\exists\)-bound variables of \(\psi\) such that \(\psi\) is then true.
</li></ul>
</li></ul>
<p class="commentary">In particular, in the case when \(\psi = \phi\), <span class="extract"><span class="extract-syntax">B</span></span> is the start of our
compiled Inter code (before anything is done) and <span class="extract"><span class="extract-syntax">A</span></span> is the magic match
position <span class="extract"><span class="extract-syntax">M</span></span>.
</p>
<p class="commentary firstcommentary"><a id="SP3_6_1_2" class="paragraph-anchor"></a><b>&#167;3.6.1.2. </b>Lemma: If the Invariant holds for two adjacent syntactically valid
subpropositions \(\mu\) and \(\nu\), then it holds for the subproposition \(\mu\nu\).
</p>
<p class="commentary">Proof of lemma: There are now three positions in the code: <span class="extract"><span class="extract-syntax">B1</span></span>, before \(\mu\);
<span class="extract"><span class="extract-syntax">B2</span></span>, before \(\nu\), which is the same position as after \(\mu\); and <span class="extract"><span class="extract-syntax">A</span></span>, after
\(\nu\). Execution reaches <span class="extract"><span class="extract-syntax">B2</span></span> \(m\) times for each visit to <span class="extract"><span class="extract-syntax">B1</span></span>, where \(m\)
is the number of combinations of viable bound variable values in \(\mu\).
Execution reaches <span class="extract"><span class="extract-syntax">A</span></span> \(n\) times for each visit to <span class="extract"><span class="extract-syntax">B2</span></span>, where \(n\) is the
similar number for \(\nu\). Therefore execution reaches <span class="extract"><span class="extract-syntax">A</span></span> a total of \(nm\)
times for each visit to <span class="extract"><span class="extract-syntax">B1</span></span>, the product of the number of variable combinations
in \(\mu\) and \(\nu\), which is exactly the number of combinations in total.
</p>
<p class="commentary">Corollary: If the Invariant holds for subpropositions in each of
the following forms, then it will hold overall:
</p>
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">Exists v</span></span>, for some variable \(v\), or <span class="extract"><span class="extract-syntax">Q v IN[ ... IN]</span></span>, for some quantifier other than \(\exists\).
</li><li>(b) <span class="extract"><span class="extract-syntax">NOT[ ... NOT]</span></span>.
</li><li>(c) Any single predicate-like atom.
</li></ul>
<p class="commentary">Proof of corollary: All valid subpropositions are concatenations of (a) to (c),
and we then apply the Lemma inductively.
</p>
<p class="commentary">It follows that if we can prove our algorithm maintains the invariant in
cases (a) to (c), we can be sure it will correctly construct code leading
to the match point <span class="extract"><span class="extract-syntax">M</span></span>.
</p>
<p class="commentary firstcommentary"><a id="SP3_6_1_3" class="paragraph-anchor"></a><b>&#167;3.6.1.3. </b>We will make use of four stacks:
</p>
<ul class="items"><li>(a) The R-stack, which holds the current "reason": the goal being pursued
by the Inter code currently being compiled.
</li><li>(b) The Q-stack, which holds details of quantifiers being searched on.
</li><li>(c) The C-stack, which holds details of callings of variables.
</li><li>(d) The L-stack, which records hierarchical levels in the Inter code generated.
The current stack pointer <span class="extract"><span class="extract-syntax">L_sp</span></span> for this is equivalent to the depth of nesting
of the Inter code being generated.
</li></ul>
<p class="commentary">Each stack begins empty: we want to be absolutely sure that this algorithm
behaves as expected, so internal errors are thrown if any stack underflows,
overflows, or is other than empty again at the end. The maximum capacity in each
case is tied either to the number of distinct predicate calculus variables, or
the number of quantifiers, and in either case is at worst 26. But the R-stack
potentially needs one more slot to hold the outermost reason, so we'll just
give them all a capacity of 27.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">Q_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">C_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">r_stack_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">; </span><span class="comment-syntax"> what task are we performing? A </span><span class="extract"><span class="extract-syntax">*_DEFER</span></span><span class="comment-syntax"> value</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parity</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">TRUE</span></span><span class="comment-syntax"> if we want a match, </span><span class="extract"><span class="extract-syntax">FALSE</span></span><span class="comment-syntax"> if we want no match</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">r_stack_data</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">q_stack_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quant</span><span class="plain-syntax">; </span><span class="comment-syntax"> which quantifier</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parameter</span><span class="plain-syntax">; </span><span class="comment-syntax"> its parameter, e.g., 9 for "more than nine"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_stack_level</span><span class="plain-syntax">; </span><span class="comment-syntax"> at the point this occurs</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L_stack_level</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">existential</span><span class="plain-syntax">; </span><span class="comment-syntax"> just one solution is needed</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">q_stack_data</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">c_stack_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">term</span><span class="plain-syntax">; </span><span class="comment-syntax"> the term to which a calling is being given</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stash_index</span><span class="plain-syntax">; </span><span class="comment-syntax"> its index in the stash of callings</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">c_stack_data</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">l_stack_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">; </span><span class="comment-syntax"> Inter emission level at start of code block</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">l_stack_data</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure r_stack_data is accessed in 4/dtd and here.</li><li>The structure q_stack_data is private to this section.</li><li>The structure c_stack_data is private to this section.</li><li>The structure l_stack_data is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4" class="paragraph-anchor"></a><b>&#167;3.6.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to search for valid combinations of variables</span><span class="named-paragraph-number">3.6.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">r_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">q_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">Q_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">c_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">C_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">l_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Push initial reason onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> we now begin compiling the search code</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2" class="named-paragraph-link"><span class="named-paragraph">Compile the proposition into a search algorithm</span><span class="named-paragraph-number">3.6.1.4.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_4" class="named-paragraph-link"><span class="named-paragraph">Pop the Q-stack</span><span class="named-paragraph-number">3.6.1.4.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_5" class="named-paragraph-link"><span class="named-paragraph">Pop the C-stack</span><span class="named-paragraph-number">3.6.1.4.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> we are now at the magic match point </span><span class="extract"><span class="extract-syntax">M</span></span><span class="comment-syntax"> in the search code</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3" class="named-paragraph-link"><span class="named-paragraph">Pop the R-stack</span><span class="named-paragraph-number">3.6.1.4.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_6" class="named-paragraph-link"><span class="named-paragraph">Pop the L-stack</span><span class="named-paragraph-number">3.6.1.4.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> we have now finished compiling the search code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R-stack failure"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Q-stack failure"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"C-stack failure"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack failure"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.1. The R-stack. </b>This is a sort of "split goals into sub-goals" mechanism. In order to
determine, say, "if all but one of the closed doors are unlocked", the main
goal is to determine the truth of the "are unlocked" part. For that example,
<span class="extract"><span class="extract-syntax">reason</span></span> will be <span class="extract"><span class="extract-syntax">CONDITION_DEFER</span></span>, and it is pushed onto the R-stack at the
start of the compilation:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push initial reason onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R-stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">reason</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reason</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">&#167;3.6.1.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.1. </b>But in order to work this out, we have to work out which doors are closed,
and this is a subgoal to which we give the pseudo-reason <span class="extract"><span class="extract-syntax">FILTER_DEFER</span></span>. We
push this new sub-goal onto the R-stack, leaving the original to be resumed
when we're done.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">FILTER_DEFER</span><span class="plain-syntax"> </span><span class="constant-syntax">10000</span><span class="plain-syntax"> </span><span class="comment-syntax"> pseudo-reason value used only inside this function</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push domain-opening onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R-stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">FILTER_DEFER</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3. </b>The R-stack is then popped when the goal is accomplished (or rather, when
the Inter code we are compiling has reached a point which will be executed when
its goal has been accomplished).
</p>
<p class="commentary">In the case of <span class="extract"><span class="extract-syntax">FILTER_DEFER</span></span>, when scanning domains of quantifiers, we increment
the count of the domain set size &mdash; the number of closed doors, in the above
example. (See below.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the R-stack</span><span class="named-paragraph-number">3.6.1.4.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R stack underflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FILTER_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Q stack underflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">-1]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_1" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in CONDITION search</span><span class="named-paragraph-number">3.6.1.4.3.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in EXTREMAL search</span><span class="named-paragraph-number">3.6.1.4.3.7</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_8" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in LOOP search</span><span class="named-paragraph-number">3.6.1.4.3.8</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in NUMBER search</span><span class="named-paragraph-number">3.6.1.4.3.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_3" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in LIST search</span><span class="named-paragraph-number">3.6.1.4.3.3</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_5" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in TOTAL search</span><span class="named-paragraph-number">3.6.1.4.3.5</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_6" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.4.3.6</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_4" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in RANDOM search</span><span class="named-paragraph-number">3.6.1.4.3.4</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">&#167;3.6.1.4</a>, <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2. Compiling the search. </b>In the following we run through the proposition from left to right, compiling
Inter code as we go, but preserving the Invariant.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the proposition into a search algorithm</span><span class="named-paragraph-number">3.6.1.4.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_deferred_callings</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> how many callings found to date</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEGATION_OPEN_ATOM:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEGATION_CLOSE_ATOM:</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> reverse parity</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">QUANTIFIER_ATOM:</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">negated_quantifier_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">quant</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">param</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Atoms::get_quantification_parameter</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> == </span><span class="identifier-syntax">exists_quantifier</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_9" class="named-paragraph-link"><span class="named-paragraph">Mark the Q-stack to show an inner existential quantifier is in play</span><span class="named-paragraph-number">3.6.1.4.2.9</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_8" class="named-paragraph-link"><span class="named-paragraph">Push the Q-stack</span><span class="named-paragraph-number">3.6.1.4.2.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_6" class="named-paragraph-link"><span class="named-paragraph">Compile a loop through possible values of the variable quantified</span><span class="named-paragraph-number">3.6.1.4.2.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_OPEN_ATOM:</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_1" class="named-paragraph-link"><span class="named-paragraph">Push domain-opening onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_CLOSE_ATOM:</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3" class="named-paragraph-link"><span class="named-paragraph">Pop the R-stack</span><span class="named-paragraph-number">3.6.1.4.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">CreationPredicates::is_calling_up_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_10" class="named-paragraph-link"><span class="named-paragraph">Push the C-stack</span><span class="named-paragraph-number">3.6.1.4.2.10</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_5" class="named-paragraph-link"><span class="named-paragraph">Compile code to force the atom</span><span class="named-paragraph-number">3.6.1.4.2.5</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">first_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ex</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ex</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">CreationPredicates::is_calling_up_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">ex</span><span class="plain-syntax">))) </span><span class="identifier-syntax">ex</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ex</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ex</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">ex</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEGATION_OPEN_ATOM:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEGATION_CLOSE_ATOM:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">QUANTIFIER_ATOM:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_OPEN_ATOM:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_CLOSE_ATOM:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_3" class="named-paragraph-link"><span class="named-paragraph">Compile code to test the atom</span><span class="named-paragraph-number">3.6.1.4.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">&#167;3.6.1.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_2" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.2. Predicate runs and their negations. </b>Or, cheating Professor de Morgan.
</p>
<p class="commentary">If we have a run of predicate-like atoms &mdash; say X, Y, Z &mdash; then this amounts
to a conjunction: \(X\land Y\land Z\). The obvious way to compile code for this
would be to take one term at a time:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if (X)</span>
<span class="plain-syntax"> if (Y)</span>
<span class="plain-syntax"> if (Z)</span>
</pre>
<p class="commentary">That satisfies the Invariant, and is clearly correct. But we want to use the
same mechanism when looking at a negation, and then it would go wrong.
</p>
<p class="commentary">Note that if \(\phi\) contains \(\lnot(\psi)\) then \(\psi\) must be a
conjunction of predicate-like atoms. (Otherwise a problem message would be
issued and in that case it doesn't matter what code we compile, so long as
we don't crash: it will never be run.) Thus we can assume that between
<span class="extract"><span class="extract-syntax">NEGATION_OPEN_ATOM</span></span> and <span class="extract"><span class="extract-syntax">NEGATION_CLOSE_ATOM</span></span> is a predicate run.
</p>
<p class="commentary">Between negation brackets, then, we must interpret X, Y, Z as
\(\lnot(X\land Y\land Z)\), and we need to compile that to
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if (~~(X &amp;&amp; Y &amp;&amp; Z))</span>
</pre>
<p class="commentary">rather than
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if (~~X)</span>
<span class="plain-syntax"> if (~~Y)</span>
<span class="plain-syntax"> if (~~Z)</span>
</pre>
<p class="commentary">which gets de Morgan's laws wrong.
</p>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_3" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.3. </b>That means a little fancy footwork to start and finish the compound <span class="extract"><span class="extract-syntax">if</span></span>
statement properly:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to test the atom</span><span class="named-paragraph-number">3.6.1.4.2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_in_run</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">NOT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">last_in_run</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-ca.html#SP1" class="function-link"><span class="function-syntax">CompileAtoms::code_to_perform</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">TEST_ATOM_TASK</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_4" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">(); </span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax">--; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the Inter code compiled to perform the search, if variant</span><span class="named-paragraph-number">3.6.1.4.2.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a> (five times).</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_5" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.5. </b>The <span class="extract"><span class="extract-syntax">NOW_ASSERTION_DEFER</span></span> reason is different from all of the others,
because rather than searching for a given situation it tries force it to
happen (or not to). Forcing rather than testing is easy here: we just supply
a different task when calling <a href="4-ca.html#SP1" class="internal">CompileAtoms::code_to_perform</a>.
</p>
<p class="commentary">In the negated case, we again cheat de Morgan, by falsifying \(\phi\) more
aggressively than we need: we force \(\lnot(X)\land\lnot(Y)\land\lnot(Z)\) to
be true, though strictly speaking it would be enough to falsify X alone.
(We do it that way for consistency with the same convention when asserting
about the model world.) But we don't need to consider runs of predicates for
that; we can take the atoms one at a time.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to force the atom</span><span class="named-paragraph-number">3.6.1.4.2.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="4-ca.html#SP1" class="function-link"><span class="function-syntax">CompileAtoms::code_to_perform</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax">)?</span><span class="identifier-syntax">NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_6" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.6. Quantifiers and the Q-stack. </b>It remains to deal with quantifiers, and to show that the Invariant is
preserved by them. There are two cases: \(\exists\), and everything else.
</p>
<p class="commentary">The existence case is the easiest. Given \(\exists v: \psi(v)\) we compile
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> loop header for v to run through its domain set {</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">arranging that execution reaches the start of the loop body once for each
possible choice of \(v\), as required by the Invariant.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile a loop through possible values of the variable quantified</span><span class="named-paragraph-number">3.6.1.4.2.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level_back_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0].</span><span class="identifier-syntax">variable</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0].</span><span class="identifier-syntax">variable</span><span class="plain-syntax">],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> != </span><span class="identifier-syntax">exists_quantifier</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the Inter code compiled to perform the search</span><span class="named-paragraph-number">3.6.1.4.2.6.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_7" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.7. </b>Generalised quantifiers &mdash; "at least three", "all but four", and
so on &mdash; make quantitative statements about the number of valid or invalid
cases over a domain set. These need more elaborate code. Suppose we have
\(\phi = Q v\in\lbrace v\mid\psi(v)\rbrace: \theta(v)\), which in memory
looks like this:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> QUANTIFIER --&gt; DOMAIN_OPEN --&gt; psi --&gt; DOMAIN_CLOSE --&gt; theta</span>
</pre>
<p class="commentary">We compile that to code in the following shape:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> set count of domain size to 0</span>
<span class="plain-syntax"> set count of valid cases to 0</span>
<span class="plain-syntax"> loop header for v to run through its domain set {</span>
<span class="plain-syntax"> if psi holds {</span>
<span class="plain-syntax"> increment count of domain size</span>
<span class="plain-syntax"> if theta holds {</span>
<span class="plain-syntax"> increment count of valid cases</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> if the counts are such that the quantifier is satisfied {</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">We don't always need both counts. For instance, to handle "at least three
doors are unlocked" we count both the domain size (the number of doors)
and the number of valid cases (the number of unlocked doors), but only need
the latter. This might be worth optimising some day, to save local variables.
</p>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_8" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.8. </b>The domain size and valid case counts are stored in locals called <span class="extract"><span class="extract-syntax">qcn_N</span></span>
and <span class="extract"><span class="extract-syntax">qcy_N</span></span> respectively, where <span class="extract"><span class="extract-syntax">N</span></span> is the index of the quantifier &mdash; 0 for
the first one in the proposition, 1 for the second and so on.
</p>
<p class="commentary">On reading a non-existence <span class="extract"><span class="extract-syntax">QUANTIFIER</span></span> atom, we compile code to zero the
counts, and push details of the quantifier onto the Q-stack, so that we
can recover them later. We then compile a loop header exactly as above.
</p>
<p class="commentary">The test of \(\psi\), which acts as a filter on the domain set &mdash; e.g.,
only doors, not all objects &mdash; is handled by pushing a suitable goal onto
the R-stack, but we don't need to do anything to make that happen here,
because the <span class="extract"><span class="extract-syntax">DOMAIN_OPEN</span></span> atom does it.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push the Q-stack</span><span class="named-paragraph-number">3.6.1.4.2.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_8_1" class="named-paragraph-link"><span class="named-paragraph">Handle "not exists" as "for all not"</span><span class="named-paragraph-number">3.6.1.4.2.8.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">quant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">quant</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parameter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">param</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">L_stack_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">C_stack_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">existential</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_9" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.9. </b>Existential quantifiers are not pushed to the Q-stack, because they are
by definition about finding the first solution, not counting solutions. But
we need to record their presence anyway:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Mark the Q-stack to show an inner existential quantifier is in play</span><span class="named-paragraph-number">3.6.1.4.2.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">existential</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_8_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.8.1. </b>It is always true that \(\not\exists x: \psi(x)\) is equivalent to $\forall x:
\lnot(\phi(x))$, so the following seems pointless. We do this, in the case
of "now" only, in order to make \(\not\exists\) legal in a "now", which
it otherwise wouldn't be. Most quantifiers aren't, because they are too vague:
"now fewer than six doors are open", for instance, is not allowed. But we
do want to allow "now nobody likes Mr Wickham", say, which asserts
\(\not\exists x: {\it person}(x)\land{\it likes}(x, W)\).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle "not exists" as "for all not"</span><span class="named-paragraph-number">3.6.1.4.2.8.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_exists_quantifier</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">quant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">for_all_quantifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2_8">&#167;3.6.1.4.2.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_4" class="paragraph-anchor"></a><b>&#167;3.6.1.4.4. </b>To resume the narrative of what happens when we read:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> QUANTIFIER --&gt; DOMAIN_OPEN --&gt; psi --&gt; DOMAIN_CLOSE --&gt; theta</span>
</pre>
<p class="commentary">We zeroed the counters, compiled the loop headers and pushed details to the
Q-stack at the <span class="extract"><span class="extract-syntax">QUANTIFIER</span></span> atom; pushed a filtering goal onto the R-stack
at the <span class="extract"><span class="extract-syntax">DOMAIN_OPEN</span></span> atom; popped it again as accomplished at <span class="extract"><span class="extract-syntax">DOMAIN_CLOSE</span></span>,
compiling a line which increments the domain size to celebrate; and then
compiled code to test \(\theta\).
</p>
<p class="commentary">Now we are at the end of the line, and still have the quantifier code
half-done, as we know because the Q-stack is not empty. We first compile
an increment of the valid cases count, because if execution of the Inter
code gets to the end of testing \(\theta\) then it must have found a valid
case: in the "at least three doors are unlocked" example, it will have
found an unlocked one among the doors making up the domain. We then need
to record any "called" values for later retrieval by whoever called
this proposition function: see below. That leaves just this part:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> if the counts are such that the quantifier is satisfied {</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">left to compile, and we will be done: execution will reach the <span class="extract"><span class="extract-syntax">...</span></span> if and
only if it is true at run-time that three or more of the doors is unlocked.
</p>
<p class="commentary">Thus this elaborate generalised-quantifier case satisfies the Invariant
because it transfers execution from before to <span class="extract"><span class="extract-syntax">...</span></span> either 0 times (if the
counts don't satisfy us), or once. Unlike in the \(\exists v\) case, it's
not a question of enumerating which \(v\) work and which do not; the whole
thing works, or doesn't, and is more like testing a single <span class="extract"><span class="extract-syntax">if</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the Q-stack</span><span class="named-paragraph-number">3.6.1.4.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Q stack underflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_4_1" class="named-paragraph-link"><span class="named-paragraph">Count this as a success</span><span class="named-paragraph-number">3.6.1.4.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">C_stack_level</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_5" class="named-paragraph-link"><span class="named-paragraph">Pop the C-stack</span><span class="named-paragraph-number">3.6.1.4.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">L_stack_level</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_6" class="named-paragraph-link"><span class="named-paragraph">Pop the L-stack</span><span class="named-paragraph-number">3.6.1.4.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Quantifiers::emit_test</span><span class="plain-syntax">(</span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">quant</span><span class="plain-syntax">, </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parameter</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">], </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the Inter code compiled to perform the search, if variant</span><span class="named-paragraph-number">3.6.1.4.2.4.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">&#167;3.6.1.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_4_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.4.1. </b>Note that if there is an existential quantifier inside the quantifier we
are counting solutions for, then we halt the search as soon as a solution is found;
we don't want to rack up <span class="extract"><span class="extract-syntax">qcy_s[Q_sp]</span></span> to artificially high levels by finding
multiple solutions. See test case <span class="extract"><span class="extract-syntax">CountInnerExistential</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Count this as a success</span><span class="named-paragraph-number">3.6.1.4.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">existential</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">BREAK_BIP</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_4">&#167;3.6.1.4.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_10" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.10. The C-stack. </b>When a CALLED atom in the proposition gives a name to a variable, we have to
transcribe that to the stash of callings for the benefit of the code
calling this proposition function. Each time we discover that a term \(t\) is
to be given a name, we stack it up. These are not always variables:
</p>
<blockquote>
<p>if a person (called the dupe) is in a dark room (called the lair), ...</p>
</blockquote>
<p class="commentary">gives names to \(x\) ("dupe") and \(f_{\it in}(x)\) ("lair"), because
simplification has eliminated the variable \(y\) which appears to be being
given a name.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push the C-stack</span><span class="named-paragraph-number">3.6.1.4.2.10</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">C_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"C-stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">stash_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">no_deferred_callings</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">&#167;3.6.1.4.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_5" class="paragraph-anchor"></a><b>&#167;3.6.1.4.5. </b>When does the compiled search code record values into the stash of callings?
In two situations:
</p>
<ul class="items"><li>(a) when a domain-search has successfully found a viable case for a quantifier,
the values of any variables called in that domain are recorded;
</li><li>(b) and otherwise the values of called variables are recorded just before
point <span class="extract"><span class="extract-syntax">M</span></span>, that is, immediately before acting on a successful match.
</li></ul>
<p class="commentary">For example, when reading:
</p>
<blockquote>
<p>if a person (called the dupe) is in a lighted room which is adjacent to exactly one dark room (called the lair), ...</p>
</blockquote>
<p class="commentary">the value of "dupe" is transferred just before <span class="extract"><span class="extract-syntax">M</span></span>, but the value of "lair"
is transferred as soon as a dark room is found. The code looks like this:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> set count of domain size to 1</span>
<span class="plain-syntax"> loop through domain (i.e., dark rooms adjacent to the person's location) {</span>
<span class="plain-syntax"> increment count of domain size</span>
<span class="plain-syntax"> record the lair value</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> if the count of domain size is 1 {</span>
<span class="plain-syntax"> record the dupe value</span>
<span class="plain-syntax"> M</span>
<span class="plain-syntax"> }</span>
</pre>
<p class="commentary">If we waited until point <span class="extract"><span class="extract-syntax">M</span></span> to record the lair value, it would have disappeared,
because <span class="extract"><span class="extract-syntax">M</span></span> is outside the loop which searches the domain of the "exactly one"
quantifier.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the C-stack</span><span class="named-paragraph-number">3.6.1.4.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"C stack underflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::reference</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOOKUP_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="3-lp.html#SP5" class="function-link"><span class="function-syntax">LocalParking::callings</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">stash_index</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="4-cs.html#SP5" class="function-link"><span class="function-syntax">CompileSchemas::compile_term</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">term</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">&#167;3.6.1.4</a>, <a href="4-cdp.html#SP3_6_1_4_4">&#167;3.6.1.4.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_6_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.6.1. </b>Opening a block is the same thing as pushing to the L-stack:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open a block in the Inter code compiled to perform the search</span><span class="named-paragraph-number">3.6.1.4.2.6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">].</span><span class="element-syntax">level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">level_back_to</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2_6">&#167;3.6.1.4.2.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_4_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.2.4.1. </b>Not for a loop body:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open a block in the Inter code compiled to perform the search, if variant</span><span class="named-paragraph-number">3.6.1.4.2.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">].</span><span class="element-syntax">level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">()-1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2_4">&#167;3.6.1.4.2.4</a>, <a href="4-cdp.html#SP3_6_1_4_4">&#167;3.6.1.4.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_6" class="paragraph-anchor"></a><b>&#167;3.6.1.4.6. </b>Close a block in the Inter code compiled to perform the search:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the L-stack</span><span class="named-paragraph-number">3.6.1.4.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack underflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">() &gt; </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">level</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">--;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">&#167;3.6.1.4</a>, <a href="4-cdp.html#SP3_6_1_4_4">&#167;3.6.1.4.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_3" class="paragraph-anchor"></a><b>&#167;3.5.3. Adaptations. </b>That completes the general pattern of searching according to the proposition's
instructions. It remains to adapt it to different needs, by providing, in
each case, some setting-up code; some code to execute when a viable set
of variable values is found; and some winding-up code.
</p>
<p class="commentary">In some of the cases, additional local variables are needed within the
<span class="extract"><span class="extract-syntax">Prop_N</span></span> function, to keep track of counters or totals. These are they:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the Inter locals needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"selection"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best_with"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"selection"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best_with"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">&#167;3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_4" class="paragraph-anchor"></a><b>&#167;3.5.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the Inter call parameters needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((!</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">LIST_OF_DEFER</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">list_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"list"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"strong_kind"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">&#167;3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_5" class="paragraph-anchor"></a><b>&#167;3.6.1.5. Adaptation to CONDITION. </b>The first and simplest of our cases to understand: where \(\phi\) is a sentence,
with all variables bound, and we have to return <span class="extract"><span class="extract-syntax">true</span></span> if it is true and
<span class="extract"><span class="extract-syntax">false</span></span> if it is false. There is no initialisation:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before CONDITION search</span><span class="named-paragraph-number">3.6.1.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> ;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.1. </b>As soon as we find any valid combination of the variables, we return <span class="extract"><span class="extract-syntax">true</span></span>:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in CONDITION search</span><span class="named-paragraph-number">3.6.1.4.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::rtrue</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_6" class="paragraph-anchor"></a><b>&#167;3.6.1.6. </b>So we only reach winding-up if every case failed, and then we return <span class="extract"><span class="extract-syntax">false</span></span>:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after CONDITION search</span><span class="named-paragraph-number">3.6.1.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::rfalse</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_7" class="paragraph-anchor"></a><b>&#167;3.6.1.7. Adaptation to NUMBER. </b>In the remaining cases, \(\phi\) has variable \(x\) (only) left free, but the use
we want to make will be a loop over all objects \(x\), and we compile this
"outer loop" here: the loop opens in the initialisation code, closes in
the winding-up code, and therefore completely encloses the code generated
by the searching mechanism above.
</p>
<p class="commentary">In the first case, we want to count the number of \(x\) for which \(\phi(x)\)
is true. The local <span class="extract"><span class="extract-syntax">counter</span></span> holds the count so far; it starts out automatically
at 0, since all Inter locals do.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before NUMBER search</span><span class="named-paragraph-number">3.6.1.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_2" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.2. </b>Recall that we get here for each possible way that \(\phi(x)\) could
be true, that is, once for each viable set of values of bound variables in
\(\phi\). But we only want to increment <span class="extract"><span class="extract-syntax">counter</span></span> once, so having done so, we
exit the searching code and continue the outer loop.
</p>
<p class="commentary">The <span class="extract"><span class="extract-syntax">jump</span></span> to a label is forced on us since Inter, unlike, say, Perl, has no
syntax to break or continue a loop other than the innermost one.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in NUMBER search</span><span class="named-paragraph-number">3.6.1.4.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_2_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="string-syntax">".NextOuterLoop_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] = </span><span class="identifier-syntax">EmitCode::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">JUMP_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::lab</span><span class="plain-syntax">(</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3_2">&#167;3.6.1.4.3.2</a>, <a href="4-cdp.html#SP3_6_1_4_3_3">&#167;3.6.1.4.3.3</a>, <a href="4-cdp.html#SP3_6_1_4_3_4">&#167;3.6.1.4.3.4</a>, <a href="4-cdp.html#SP3_6_1_4_3_5">&#167;3.6.1.4.3.5</a>, <a href="4-cdp.html#SP3_6_1_4_3_6">&#167;3.6.1.4.3.6</a>, <a href="4-cdp.html#SP3_6_1_21">&#167;3.6.1.21</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_8" class="paragraph-anchor"></a><b>&#167;3.6.1.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Place next outer loop label</span><span class="named-paragraph-number">3.6.1.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="string-syntax">".NextOuterLoop_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] = </span><span class="identifier-syntax">EmitCode::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::place_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">]);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_9" class="paragraph-anchor"></a><b>&#167;3.6.1.9. </b>The continue-outer-loop labels are marked with the reason number so that
if code is compiled for each reason in turn within a single function &mdash; which
is what we do for multipurpose deferred propositions &mdash; the labels do
not have clashing names.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after NUMBER search</span><span class="named-paragraph-number">3.6.1.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_10" class="paragraph-anchor"></a><b>&#167;3.6.1.10. Adaptation to LIST. </b>In the next case, we want to form the list of all \(x\) for which \(\phi(x)\)
is true. The local <span class="extract"><span class="extract-syntax">list</span></span> holds the list so far, and already exists.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before LIST search</span><span class="named-paragraph-number">3.6.1.10</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">BLKVALUEWRITE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_ITEM_KOV_F_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">strong_kind_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_GETLENGTH_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_3" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.3. </b>Recall that we get here for each possible way that \(\phi(x)\) could
be true, that is, once for each viable set of values of bound variables in
\(\phi\). But we only want to increment <span class="extract"><span class="extract-syntax">counter</span></span> once, so having done so, we
exit the searching code and continue the outer loop.
</p>
<p class="commentary">The <span class="extract"><span class="extract-syntax">jump</span></span> to a label is forced on us since Inter, unlike, say, Perl, has no
syntax to break or continue a loop other than the innermost one.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in LIST search</span><span class="named-paragraph-number">3.6.1.4.3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(3);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(2);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(8);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_SETLENGTH_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">BLKVALUEWRITE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">MINUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_ITEM_BASE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(1);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_11" class="paragraph-anchor"></a><b>&#167;3.6.1.11. </b>The continue-outer-loop labels are marked with the reason number so that
if code is compiled for each reason in turn within a single function &mdash; which
is what we do for multipurpose deferred propositions &mdash; the labels do
not have clashing names.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after LIST search</span><span class="named-paragraph-number">3.6.1.11</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_SETLENGTH_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_12" class="paragraph-anchor"></a><b>&#167;3.6.1.12. Adaptation to RANDOM. </b>To choose a random \(x\) such that \(\phi(x)\), we essentially run the same code
as for NUMBER searches, but twice over: first to count how many such \(x\) there
are, then to run through again to find the \(n\)th of these, where \(n\) is a
uniformly random number such that \(1\leq n\leq x\).
</p>
<p class="commentary">This avoids needing to store the full list of matches anywhere, which would
be impossible since (a) it's potentially a lot of storage and (b) it can
only safely live on the current stack frame, and Inter does not allow arrays
on the current stack frame (because of restrictions in the Z-machine).
This means that, on average, the compiled code takes 50\% longer to find
its random \(x\) than it ideally would, but we accept the trade-off.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before RANDOM search</span><span class="named-paragraph-number">3.6.1.12</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) -1);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">WHILE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_true</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_4" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.4. </b>Again we exit the searcher as soon as a match is found, since that guarantees
that \(\phi(x)\).
</p>
<p class="commentary">Note that we can only return here on the second pass, since <span class="extract"><span class="extract-syntax">selection</span></span> is \(-1\)
throughout the first pass, whereas <span class="extract"><span class="extract-syntax">counter</span></span> is non-negative.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in RANDOM search</span><span class="named-paragraph-number">3.6.1.4.3.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_13" class="paragraph-anchor"></a><b>&#167;3.6.1.13. </b>We return <span class="extract"><span class="extract-syntax">nothing</span></span> &mdash; the non-object &mdash; if <span class="extract"><span class="extract-syntax">counter</span></span> is zero, since that
means the set of possible \(x\) is empty. But we also return if <span class="extract"><span class="extract-syntax">selection</span></span>
has been made already, because that means that the second pass has been
completed without a return &mdash; something which in theory cannot happen, but
just might do if testing part of the proposition had some side-effect changing
the state of the objects and thus the size of the set of possibilities.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after RANDOM search</span><span class="named-paragraph-number">3.6.1.13</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">OR_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_nothing</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RANDOM_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_14" class="paragraph-anchor"></a><b>&#167;3.6.1.14. Adaptation to TOTAL. </b>Here the task is to sum the values of property \(P\) attached to each object
in the domain \(\lbrace x\mid \phi(x)\rbrace\).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before TOTAL search</span><span class="named-paragraph-number">3.6.1.14</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_15" class="paragraph-anchor"></a><b>&#167;3.6.1.15. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.15</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_5" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.5. </b>The only wrinkle here is the way the compiled code knows which property it
should be totalling. If we know that ourselves, we can compile in a direct
reference. But if we are compiling a multipurpose deferred proposition, then
it might be used to total any property over the domain, and we won't know
which until runtime &mdash; when its identity will be found in the Inter variable
<span class="extract"><span class="extract-syntax">property_to_be_totalled</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in TOTAL search</span><span class="named-paragraph-number">3.6.1.4.3.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTKindIDs::weak_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTProperties::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_6" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.4.3.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_PLUS_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTKindIDs::weak_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTProperties::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_16" class="paragraph-anchor"></a><b>&#167;3.6.1.16. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after TOTAL search</span><span class="named-paragraph-number">3.6.1.16</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_17" class="paragraph-anchor"></a><b>&#167;3.6.1.17. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.17</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_18" class="paragraph-anchor"></a><b>&#167;3.6.1.18. Adaptation to EXTREMAL. </b>This is rather similar. We find the member of \(\lbrace x\mid \phi(x)\rbrace\)
which either minimises, or maximises, the value of some property \(P\). We use
two local variables: <span class="extract"><span class="extract-syntax">best</span></span>, the extreme \(P\) value found so far; and <span class="extract"><span class="extract-syntax">best_with</span></span>,
the member of the domain set which achieves that.
</p>
<p class="commentary">If two or more \(x\) achieve the optimal \(P\)-value, it is deliberately left
undefined which one is returned. The user may be typing "the heaviest thing
on the table", but what he gets is "a heaviest thing on the table".
</p>
<p class="commentary">We open the search with <span class="extract"><span class="extract-syntax">best_with</span></span> equal to <span class="extract"><span class="extract-syntax">nothing</span></span>, the non-object, which
is what we will return if the domain set turns out to be empty; and with
<span class="extract"><span class="extract-syntax">best</span></span> set to the furthest-from-optimal value possible. For a search maximising
\(P\), <span class="extract"><span class="extract-syntax">best</span></span> starts at the lowest number representable in the virtual machine;
for a minimisation, it starts at the highest. That way, if any member of the
domain is found, its \(P\)-value must be at least as good as the starting
value of <span class="extract"><span class="extract-syntax">best</span></span>.
</p>
<p class="commentary">Again the only nuisance is that sometimes we know \(P\), and whether we are
maximising or minimising, at compile time; but for a multipurpose function
we don't, and have to look that up at run-time.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before EXTREMAL search</span><span class="named-paragraph-number">3.6.1.18</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFELSE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_LOOP_SIGN_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MIN_NEGATIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MAX_POSITIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">measurement_definition</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mdef</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RETRIEVE_POINTER_measurement_definition</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Measurements::read_property_details</span><span class="plain-syntax">(</span><span class="identifier-syntax">mdef</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">def_prn</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">def_prn_sign</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">def_prn_sign</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MIN_NEGATIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MAX_POSITIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_7" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.7. </b>It might look as if we could speed up the multipurpose case by
multiplying by <span class="extract"><span class="extract-syntax">property_loop_sign</span></span>, thus combining the max and min
versions into one, and saving an <span class="extract"><span class="extract-syntax">if</span></span>. But (a) the multiplication is as
expensive as the <span class="extract"><span class="extract-syntax">if</span></span> (remember that on a VM there's no real branch
penalty), and (b) we need to watch out because \(-1\) times \(-32768\), on a
16-bit machine, is \(-1\), not \(32768\): so it is not always true that
multiplying by \(-1\) is order-reversing.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in EXTREMAL search</span><span class="named-paragraph-number">3.6.1.4.3.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFELSE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_LOOP_SIGN_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">LE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">def_prn_sign</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">LE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_7_1" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTKindIDs::weak_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTProperties::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">def_prn</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3_7">&#167;3.6.1.4.3.7</a> (6 times).</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_19" class="paragraph-anchor"></a><b>&#167;3.6.1.19. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after EXTREMAL search</span><span class="named-paragraph-number">3.6.1.19</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_20" class="paragraph-anchor"></a><b>&#167;3.6.1.20. Adaptation to LOOP. </b>Here the proposition is used to iterate through the members of the domain
set \(\lbrace x\mid \phi(x)\rbrace\). Two local variables exist: <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">x_ix</span></span>.
One of the following is true:
</p>
<ul class="items"><li>(1) The domain set contains only objects, so that <span class="extract"><span class="extract-syntax">x</span></span> is non-zero if it
represents a member of that set. In this case <span class="extract"><span class="extract-syntax">x_ix</span></span> may or may not be used,
and we will not rely on it.
</li><li>(2) The domain set contains only values, and then <span class="extract"><span class="extract-syntax">x</span></span> might easily be zero,
but <span class="extract"><span class="extract-syntax">x_ix</span></span> is always the index within the domain set: 1 if <span class="extract"><span class="extract-syntax">x</span></span> is the first
value, 2 for the second and so on.
</li></ul>
<p class="commentary">The proposition is called with a pair of values <span class="extract"><span class="extract-syntax">x</span></span>, <span class="extract"><span class="extract-syntax">x_ix</span></span> and returns
the next value <span class="extract"><span class="extract-syntax">x</span></span> in the domain set, or 0 if the domain is exhausted. (In
case (2) it's not safe to regard 0 as an end-of-set sentinel value because
0 can be a valid member of the set; so in looping through (2) we should
first find the size of the set using NUMBER OF, then keep calling for
members until the index reaches the size.) There is no need to return the
next <span class="extract"><span class="extract-syntax">x_ix</span></span> value since it is always the present value plus 1.
</p>
<p class="commentary">If the proposition is called with <span class="extract"><span class="extract-syntax">x</span></span> set to <span class="extract"><span class="extract-syntax">nothing</span></span>, in case (1), or
with <span class="extract"><span class="extract-syntax">x_ix</span></span> equal to 0, in case (2), it returns the first value in the
domain.
</p>
<p class="commentary firstcommentary"><a id="SP3_6_1_21" class="paragraph-anchor"></a><b>&#167;3.6.1.21. </b>Snarkily, this is how we do it:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if we're called with a valid member of the domain, go to Z</span>
<span class="plain-syntax"> loop x over members of the domain {</span>
<span class="plain-syntax"> return x</span>
<span class="plain-syntax"> label Z is here</span>
<span class="plain-syntax"> }</span>
</pre>
<p class="commentary">Which is not really a loop at all, but is a cheap way to extract either the
initial value or the successor value from a loop header.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> This trick caused some consternation for I6 hackers when early drafts of
I7 came out, because they had been experimenting with a patch to I6 which
protected <span class="extract"><span class="extract-syntax">objectloop</span></span> from object-tree rearrangements but which assumed that
nobody ever used <span class="extract"><span class="extract-syntax">jump</span></span> to enter a loop body bypassing its header. But the DM4,
which defines I6, does not forbid this, and nor does Inter.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before LOOP search</span><span class="named-paragraph-number">3.6.1.21</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTDECREMENT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_8" class="paragraph-anchor"></a><b>&#167;3.6.1.4.3.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in LOOP search</span><span class="named-paragraph-number">3.6.1.4.3.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">&#167;3.6.1.4.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_6_1_22" class="paragraph-anchor"></a><b>&#167;3.6.1.22. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after LOOP search</span><span class="named-paragraph-number">3.6.1.22</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_nothing</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">&#167;3.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Compiling loop headers. </b>The final task of this entire chapter is to compile an Inter loop header which
causes a given variable \(v\) to range through a domain set \(D\) &mdash; which we
have to deduce by looking at the proposition \(\psi\) in front of us.
</p>
<p class="commentary">We want this loop to run as quickly as possible: efficiency here makes a very
big difference to the running time of compiled I7 code. Consider compiling
"everyone in the Dining Room can see an animal". Code like this would run very
slowly:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> loop over objects (x)</span>
<span class="plain-syntax"> loop over objects (y)</span>
<span class="plain-syntax"> if x is a person</span>
<span class="plain-syntax"> if x is in the Dining Room</span>
<span class="plain-syntax"> if y is an animal</span>
<span class="plain-syntax"> if x can see y</span>
<span class="plain-syntax"> success!</span>
</pre>
<p class="commentary">This is folly in so many ways. Most objects are not people or animals, so
almost all combinations of \(x\) and \(y\) are wasted. We test the eligibility
of \(x\) for every possible \(y\). And there are quick ways to find what is in
the Dining Room, so we're missing a trick there, too. What we want is:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> loop over objects in the Dining Room (x)</span>
<span class="plain-syntax"> if x is a person</span>
<span class="plain-syntax"> loop over animals (y)</span>
<span class="plain-syntax"> if x can see y</span>
<span class="plain-syntax"> success!</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Part of the work is done already: we generate propositions with
quantifiers as far forwards as they can be, so we won't loop over \(y\) before
checking the validity of \(x\). The rest of the work comes from two basic
optimisations:
</p>
<ul class="items"><li>(1) "Kind optimisation." If a loop over \(v\) is such that \(K(v)\) holds in every case,
where \(K\) is a kind, then loop \(v\) over \(K\) rather than all objects, and
</li><li>(2) "Parent optimisation." If a loop over \(v\) is such that \(R(v, t)\) holds in
every case, then loop over all \(v\) such that \(R(v, t)\) in cases where \(R\) has a
run-time representation making this quick and easy.
</li></ul>
<p class="commentary">In either case we can then delete \(K(v)\) or \(R(v, t)\) from the proposition
as redundant, since the loop header has taken care of it. "Parent optimisation"
is so called because the original use of this was to do with the IF world model's
containment tree, where one object containing another is called its "parent"; but
in fact it can be applied to any suitable relation \(R\).
</p>
<p class="commentary">Parent optimisation cannot be used if we are compiling code to force a proposition,
rather than test it, because then \(R(v, t)\) is not an accomplished fact but is
something we have yet to make come true. This is why the function below needs a
flag <span class="extract"><span class="extract-syntax">avoid_parent_optimisation</span></span>. Case (1) doesn't suffer from this since
kinds cannot be changed at run-time.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">i6_schema</span><span class="plain-syntax"> </span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="function-syntax">DeferredPropositions::compile_loop_header</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></span>:<br/><a href="4-cdp.html#SP3_6_1_4_2_6">&#167;3.6.1.4.2.6</a>, <a href="4-cdp.html#SP3_6_1_7">&#167;3.6.1.7</a>, <a href="4-cdp.html#SP3_6_1_10">&#167;3.6.1.10</a>, <a href="4-cdp.html#SP3_6_1_12">&#167;3.6.1.12</a>, <a href="4-cdp.html#SP3_6_1_14">&#167;3.6.1.14</a>, <a href="4-cdp.html#SP3_6_1_15">&#167;3.6.1.15</a>, <a href="4-cdp.html#SP3_6_1_18">&#167;3.6.1.18</a>, <a href="4-cdp.html#SP3_6_1_21">&#167;3.6.1.21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">index_var</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">avoid_parent_optimisation</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">grouped</span><span class="plain-syntax">, </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">var_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Terms::new_variable</span><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">second_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Terms::new_constant</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Lvalues::new_LOCAL_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">index_var</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parent_optimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> the default, if we are unable to provide either kind or parent optimisation</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Calculus::Schemas::modify</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="string-syntax">"objectloop (*1 ofclass Object)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Scan the proposition to find the domain of the loop, and look for opportunities</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">parent_optimised</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> parent optimisation is stronger, so we prefer that</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-cl.html#SP3" class="function-link"><span class="function-syntax">CompileLoops::schema</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rtp_iname</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rtp_iname</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::make_iname_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_HL</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterNames::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ppd_iname</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Calculus::Schemas::modify</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="string-syntax">"if (RunTimeProblem(RTP_CANTITERATE, %n))"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rtp_iname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::delete_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_position</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-cs.html#SP1" class="function-link"><span class="function-syntax">CompileSchemas::from_terms_in_void_context</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">var_term</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">second_term</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b>The following looks more complicated than it really is. Sometimes it's
called to compile a loop arising from a quantifier with a domain, in
which case <span class="extract"><span class="extract-syntax">grouped</span></span> is set and <span class="extract"><span class="extract-syntax">proposition</span></span> points to:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> QUANTIFIER --&gt; DOMAIN_OPEN --&gt; psi --&gt; DOMAIN_CLOSE --&gt; ...</span>
</pre>
<p class="commentary">so that \(\psi\), the part in the domain group, defines the range of the
variable. But sometimes the call is to compile a loop not arising from a
quantifier, so there is no domain group to scan; instead the whole
proposition makes up \(\psi\), and now <span class="extract"><span class="extract-syntax">grouped</span></span> is clear.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Scan the proposition to find the domain of the loop, and look for opportunities</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">enabled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Atoms::is_opener</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Atoms::is_closer</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">grouped</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">DOMAIN_OPEN_ATOM</span><span class="plain-syntax">) </span><span class="identifier-syntax">enabled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">DOMAIN_CLOSE_ATOM</span><span class="plain-syntax">) </span><span class="identifier-syntax">enabled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">enabled</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP5_1_1" class="named-paragraph-link"><span class="named-paragraph">Scan the part of the proposition establishing the domain</span><span class="named-paragraph-number">5.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_1_1" class="paragraph-anchor"></a><b>&#167;5.1.1. </b>In either case, we scan \(\psi\) looking for \(K(v)\) atoms, which would tell
us the domain set for the variable \(v\), or for \(R(v, t)\) atoms for
parent-optimisable relations \(R\).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Scan the part of the proposition establishing the domain</span><span class="named-paragraph-number">5.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">KindPredicates::is_kind_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0].</span><span class="identifier-syntax">variable</span><span class="plain-syntax"> == </span><span class="identifier-syntax">var</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindPredicates::get_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl_prev</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">avoid_parent_optimisation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">PREDICATE_ATOM</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">arity</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP5_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Consider parent optimisation on this binary predicate</span><span class="named-paragraph-number">5.1.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP5_1">&#167;5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_1_1_1" class="paragraph-anchor"></a><b>&#167;5.1.1.1. </b>We give the relation \(R\) an opportunity to write a loop which runs \(v\)
through all possible \(x\) such that \(R(x, t)\), by writing a schema for the
loop in which <span class="extract"><span class="extract-syntax">*1</span></span> denotes the variable \(v\) and <span class="extract"><span class="extract-syntax">*2</span></span> the term \(t\).
</p>
<p class="commentary">For example, the worn-by relation writes the schema:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> objectloop (*1 in *2) if (WearerOf(*1)==parent(*1))</span>
</pre>
<p class="commentary">where \(v\) runs quickly through the object-tree children of \(t\), but items
carried rather than worn are skipped.
</p>
<p class="commentary">We have to check three possible cases: \(R(v, t)\) direct, and then
\({\it is}(f_R(v), t)\) or \({\it is}(t, f_R(v))\), which can arise from
simplifications. We set <span class="extract"><span class="extract-syntax">optimise_on</span></span> to \(R\) and <span class="extract"><span class="extract-syntax">parent</span></span> to \(t\).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider parent optimisation on this binary predicate</span><span class="named-paragraph-number">5.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">binary_predicate</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_binary_predicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">predicate</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R_equality</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">chk</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chk</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">chk</span><span class="plain-syntax">&lt;=1; </span><span class="identifier-syntax">chk</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_func</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">chk</span><span class="plain-syntax">].</span><span class="identifier-syntax">function</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pf</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pf</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fn_of</span><span class="plain-syntax">.</span><span class="identifier-syntax">variable</span><span class="plain-syntax"> == </span><span class="identifier-syntax">var</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">BinaryPredicates::write_optimised_loop_schema</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="identifier-syntax">pf</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">bp</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">second_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1-</span><span class="identifier-syntax">chk</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parent_optimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::delete_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl_prev</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0].</span><span class="identifier-syntax">variable</span><span class="plain-syntax"> == </span><span class="identifier-syntax">var</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">BinaryPredicates::write_optimised_loop_schema</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="identifier-syntax">bp</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">second_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parent_optimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::delete_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl_prev</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP5_1_1">&#167;5.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>And that finally concludes the predicate-calculus engine at the heart of Inform.
</p>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-cad.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-cv.html">2</a></li><li class="progresschapter"><a href="3-sf.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-cs.html">cs</a></li><li class="progresssection"><a href="4-ca.html">ca</a></li><li class="progresssection"><a href="4-cp.html">cp</a></li><li class="progresssection"><a href="4-cl.html">cl</a></li><li class="progresssection"><a href="4-dtd.html">dtd</a></li><li class="progresssection"><a href="4-cad.html">cad</a></li><li class="progresscurrent">cdp</li><li class="progresschapter"><a href="5-cbal.html">5</a></li><li class="progressnext"><a href="5-cbal.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>