mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
2120 lines
337 KiB
HTML
2120 lines
337 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>
|
|
|
|
<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="../compiler.html">compiler tools</a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul><h2>Compiler Webs</h2><ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul><h2>Inbuild Modules</h2><ul>
|
|
<li><a href="../supervisor-module/index.html">supervisor</a></li>
|
|
</ul><h2>Inform7 Modules</h2><ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../assertions-module/index.html">assertions</a></li>
|
|
<li><a href="../values-module/index.html">values</a></li>
|
|
<li><a href="../knowledge-module/index.html">knowledge</a></li>
|
|
<li><a href="index.html"><span class="selectedlink">imperative</span></a></li>
|
|
<li><a href="../runtime-module/index.html">runtime</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul><h2>Inter Modules</h2><ul>
|
|
<li><a href="../bytecode-module/index.html">bytecode</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul><h2>Services</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../calculus-module/index.html">calculus</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</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="../compiler.html">Inform7</a></li><li><a href="index.html">imperative</a></li><li><a href="index.html#3">Chapter 3: Compiling Propositions</a></li><li><b>Compile Deferred Propositions</b></li></ul></div>
|
|
<p class="purpose">To compile the I6 routines needed to perform the tests or tasks deferred as being too difficult in their original contexts.</p>
|
|
|
|
<ul class="toc"><li><a href="3-cdp.html#SP1">§1. Comment</a></li><li><a href="3-cdp.html#SP2">§2. Preliminaries</a></li><li><a href="3-cdp.html#SP2_1_6_1_1">§2.1.6.1.1. The Search</a></li><li><a href="3-cdp.html#SP2_1_6_1_2_1">§2.1.6.1.2.1. The R-stack</a></li><li><a href="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3. Compiling the search</a></li><li><a href="3-cdp.html#SP2_1_6_1_2_3_1">§2.1.6.1.2.3.1. Predicate runs and their negations</a></li><li><a href="3-cdp.html#SP2_1_6_1_2_3_5">§2.1.6.1.2.3.5. Quantifiers and the Q-stack</a></li><li><a href="3-cdp.html#SP2_1_6_1_2_3_8">§2.1.6.1.2.3.8. The C-stack</a></li><li><a href="3-cdp.html#SP2_1_5_1">§2.1.5.1. Adaptations</a></li><li><a href="3-cdp.html#SP2_1_6_1_3">§2.1.6.1.3. Adaptation to CONDITION</a></li><li><a href="3-cdp.html#SP2_1_6_1_5">§2.1.6.1.5. Adaptation to NUMBER</a></li><li><a href="3-cdp.html#SP2_1_6_1_8">§2.1.6.1.8. Adaptation to LIST</a></li><li><a href="3-cdp.html#SP2_1_6_1_10">§2.1.6.1.10. Adaptation to RANDOM</a></li><li><a href="3-cdp.html#SP2_1_6_1_12">§2.1.6.1.12. Adaptation to TOTAL</a></li><li><a href="3-cdp.html#SP2_1_6_1_14">§2.1.6.1.14. Adaptation to EXTREMAL</a></li><li><a href="3-cdp.html#SP2_1_6_1_16">§2.1.6.1.16. Adaptation to LOOP</a></li><li><a href="3-cdp.html#SP3">§3. Compiling loop headers</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Comment. </b>The following compiles an I6 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">Propositions::Deferred::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">Propositions::Deferred::compile_comment_about_deferral_reason</span></span>:<br/><a href="3-cdp.html#SP2_1_6">§2.1.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">Emit::code_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">Emit::code_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">Emit::code_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">Emit::code_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">Emit::code_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">Emit::code_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">Emit::code_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">RANDOM_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Emit::code_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">Emit::code_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>§2. Preliminaries. </b>We have seen that propositions are deferred for diverse reasons. Here we
|
|
take our medicine, and actually compile the deferred propositions into
|
|
routines. This is part of the phrase-compilation-coroutine process because
|
|
funny things can happen when we compile: we can create new text substitutions
|
|
which create routines which... and so on.
|
|
</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">Propositions::Deferred::compile_remaining_deferred</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="3-cdp.html#SP2" class="function-link"><span class="function-syntax">Propositions::Deferred::compilation_coroutine</span></a><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">latest_pcd</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Propositions::Deferred::compilation_coroutine</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</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">N</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">while</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">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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">latest_pcd</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"> = </span><span class="identifier-syntax">FIRST_OBJECT</span><span class="plain-syntax">(</span><span class="reserved-syntax">pcalc_prop_deferral</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">pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEXT_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">latest_pcd</span><span class="plain-syntax">, </span><span class="reserved-syntax">pcalc_prop_deferral</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"> == </span><span class="identifier-syntax">NULL</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">latest_pcd</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="3-cdp.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Compile an individual deferred proposition</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">++;</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">N</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>§2.1. </b>The basic structure of a proposition routine 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>). There therefore can't be more than 26 callings, or 26
|
|
quantifiers, either.
|
|
</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>
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile an individual deferred proposition</span><span class="named-paragraph-number">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">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><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">-></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">-></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_routine</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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 </span><span class="extract"><span class="extract-syntax">gcc -O2</span></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"> < </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="3-cdp.html#SP2_1_2" class="named-paragraph-link"><span class="named-paragraph">Simplify the proposition by flipping negated quantifiers, if possible</span><span class="named-paragraph-number">2.1.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 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">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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><span class="identifier-syntax">Routines::begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">ppd_iname</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_COMPILATION_MODE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">COMPILATION_MODE_EXIT</span><span class="plain-syntax">(</span><span class="constant-syntax">DEREFERENCE_POINTERS_CMODE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_5" class="named-paragraph-link"><span class="named-paragraph">Declare the I6 local variables which will be needed by this deferral routine</span><span class="named-paragraph-number">2.1.5</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6" class="named-paragraph-link"><span class="named-paragraph">Compile the code inside this deferral routine</span><span class="named-paragraph-number">2.1.6</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_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">2.1.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_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">2.1.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">END_COMPILATION_MODE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Routines::end</span><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">-></span><span class="element-syntax">rtp_iname</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_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">2.1.1</span></a></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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2">§2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_1" class="paragraph-anchor"></a><b>§2.1.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">2.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">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">-></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">-></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::named_string_constant</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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="3-cdp.html#SP2_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_2" class="paragraph-anchor"></a><b>§2.1.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">2.1.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">, &</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="3-cdp.html#SP2_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_3" class="paragraph-anchor"></a><b>§2.1.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 routine, 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">2.1.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="2-lv.html#SP21" class="function-link"><span class="function-syntax">LocalVariables::are_we_using_table_lookup</span></a><span class="plain-syntax">()) && (!</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="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 "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"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 "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"of checks in rather few words (and may perhaps result from "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"a misunderstanding such as writing the name of a kind where "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"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="3-cdp.html#SP2_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_4" class="paragraph-anchor"></a><b>§2.1.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">2.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">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 "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this more simply, or split it into more than one sentence?"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_5" class="paragraph-anchor"></a><b>§2.1.5. </b>Recall that an I6 function header consists of a <span class="extract"><span class="extract-syntax">[</span></span>, then an identifier
|
|
name for the function — in this case always <span class="extract"><span class="extract-syntax">Prop_N</span></span> for some number <span class="extract"><span class="extract-syntax">N</span></span> —
|
|
and then a space-delimited list of local variable names, the initial of
|
|
which are used to receive function arguments. The order of the variables
|
|
is: any cinders (constants evaluated back at deferral time and being
|
|
handed forward on the stack as function arguments); then any variables
|
|
in the predicate calculus sense, of which the first may or may not be
|
|
being used as a function argument, depending on whether or not it is
|
|
bound; then the enumeration variables needed to compile generalised
|
|
quantifiers, if any; and finally any oddball variables needed by code
|
|
specific to particular deferral reasons.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the I6 local variables which will be needed by this deferral routine</span><span class="named-paragraph-number">2.1.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_states</span><span class="plain-syntax">[26], </span><span class="identifier-syntax">no_extras</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">multipurpose_routine</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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_named_call_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="3-cad.html#SP5" class="function-link"><span class="function-syntax">Calculus::Deferrals::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="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_5_2" class="named-paragraph-link"><span class="named-paragraph">Declare the I6 call parameters needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">2.1.5.2</span></a></span><span class="plain-syntax">;</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="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax"><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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_as_symbol_noting</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</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="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>
|
|
|
|
<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">-></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"> >= </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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_5_1" class="named-paragraph-link"><span class="named-paragraph">Declare the I6 locals needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">2.1.5.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6" class="paragraph-anchor"></a><b>§2.1.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the code inside this deferral routine</span><span class="named-paragraph-number">2.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_routine</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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"> <= </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"> > </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">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="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><a href="3-cdp.html#SP1" class="function-link"><span class="function-syntax">Propositions::Deferred::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="3-cdp.html#SP2_1_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">2.1.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">-></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="3-cdp.html#SP2_1_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">2.1.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="3-cdp.html#SP2_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1" class="paragraph-anchor"></a><b>§2.1.6.1. </b>From here on, we compile the body of a routine to handle the deferral case
|
|
in the variable <span class="extract"><span class="extract-syntax">reason</span></span>.
|
|
</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">2.1.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">Produce::level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_3" class="named-paragraph-link"><span class="named-paragraph">Initialisation before CONDITION search</span><span class="named-paragraph-number">2.1.6.1.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">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_14" class="named-paragraph-link"><span class="named-paragraph">Initialisation before EXTREMAL search</span><span class="named-paragraph-number">2.1.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">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_17" class="named-paragraph-link"><span class="named-paragraph">Initialisation before LOOP search</span><span class="named-paragraph-number">2.1.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">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_5" class="named-paragraph-link"><span class="named-paragraph">Initialisation before NUMBER search</span><span class="named-paragraph-number">2.1.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">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_8" class="named-paragraph-link"><span class="named-paragraph">Initialisation before LIST search</span><span class="named-paragraph-number">2.1.6.1.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">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_12" class="named-paragraph-link"><span class="named-paragraph">Initialisation before TOTAL search</span><span class="named-paragraph-number">2.1.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="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="3-cdp.html#SP2_1_6_1_10" class="named-paragraph-link"><span class="named-paragraph">Initialisation before RANDOM search</span><span class="named-paragraph-number">2.1.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="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2" class="named-paragraph-link"><span class="named-paragraph">Compile code to search for valid combinations of variables</span><span class="named-paragraph-number">2.1.6.1.2</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">) && (</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="3-cdp.html#SP2_1_6_1_6" class="named-paragraph-link"><span class="named-paragraph">Place next outer loop label</span><span class="named-paragraph-number">2.1.6.1.6</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">Produce::level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()) > </span><span class="identifier-syntax">OL</span><span class="plain-syntax">) </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_4" class="named-paragraph-link"><span class="named-paragraph">Winding-up after CONDITION search</span><span class="named-paragraph-number">2.1.6.1.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><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="3-cdp.html#SP2_1_6_1_15" class="named-paragraph-link"><span class="named-paragraph">Winding-up after EXTREMAL search</span><span class="named-paragraph-number">2.1.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">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_18" class="named-paragraph-link"><span class="named-paragraph">Winding-up after LOOP search</span><span class="named-paragraph-number">2.1.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">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_7" class="named-paragraph-link"><span class="named-paragraph">Winding-up after NUMBER search</span><span class="named-paragraph-number">2.1.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="3-cdp.html#SP2_1_6_1_9" class="named-paragraph-link"><span class="named-paragraph">Winding-up after LIST search</span><span class="named-paragraph-number">2.1.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">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_13" class="named-paragraph-link"><span class="named-paragraph">Winding-up after TOTAL search</span><span class="named-paragraph-number">2.1.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><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="3-cdp.html#SP2_1_6_1_11" class="named-paragraph-link"><span class="named-paragraph">Winding-up after RANDOM search</span><span class="named-paragraph-number">2.1.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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6">§2.1.6</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_1" class="paragraph-anchor"></a><b>§2.1.6.1.1. The Search. </b>We can now begin the real work. Given \(\phi\), we compile I6 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
|
|
in which \(\phi\) is true.
|
|
</p>
|
|
|
|
<p class="commentary">We will do this by compiling 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. Then:
|
|
</p>
|
|
|
|
<p class="commentary">Invariant.\quad 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 I6 code for searching \(\phi\) such that
|
|
</p>
|
|
|
|
<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>
|
|
<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 I6 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">The restriction to syntactically valid subpropositions is important. Suppose
|
|
\(\phi\) arises from "all doors are open" and is stored in memory as:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> Forall x IN[ door(x) IN] open(x)</span>
|
|
</pre>
|
|
<p class="commentary">Then <span class="extract"><span class="extract-syntax">door(x)</span></span> and <span class="extract"><span class="extract-syntax">Forall x IN[ door(x) IN]</span></span> are valid, for instance, but
|
|
<span class="extract"><span class="extract-syntax">IN] open(x)</span></span> is not.
|
|
</p>
|
|
|
|
<p class="commentary">Lemma.\quad 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.\quad 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.\quad 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.\quad Because all valid subpropositions are concatenations of
|
|
these, and we then apply the Lemma.
|
|
</p>
|
|
|
|
<p class="commentary">It follows that if we can prove our algorithm maintains the invariant in
|
|
cases (a) to (d), 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="SP2_1_6_1_2" class="paragraph-anchor"></a><b>§2.1.6.1.2. </b>We will make use of three stacks:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) The R-stack, which holds the current "reason": the goal being pursued
|
|
by the I6 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></ul>
|
|
<p class="commentary">Since each is tied to a quantifier, each of which is tied to a distinct
|
|
variable, and there are at most 26 variables, we need a worst-case
|
|
capacity of 27 slots on the R-stack (counting the initial <span class="extract"><span class="extract-syntax">reason</span></span>) and
|
|
26 on the Q-stack and C-stack.
|
|
</p>
|
|
|
|
<p class="commentary"><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">2.1.6.1.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">block_nesting</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> how many </span><span class="extract"><span class="extract-syntax">{</span></span><span class="comment-syntax"> ... </span><span class="extract"><span class="extract-syntax">}</span></span><span class="comment-syntax"> blocks are open in I6 code being compiled</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> The R-stack</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_stack_reason</span><span class="plain-syntax">[27];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_stack_parity</span><span class="plain-syntax">[27];</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="comment-syntax"> The Q-stack</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Q_stack_quantifier</span><span class="plain-syntax">[26];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack_parameter</span><span class="plain-syntax">[26];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack_C_stack_level</span><span class="plain-syntax">[26];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack_block_nesting</span><span class="plain-syntax">[26];</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="comment-syntax"> The C-stack</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_stack_term</span><span class="plain-syntax">[26]; </span><span class="comment-syntax"> the term to which a called-name is being given</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_stack_index</span><span class="plain-syntax">[26]; </span><span class="comment-syntax"> its index in the </span><span class="extract"><span class="extract-syntax">deferred_calling_list</span></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="comment-syntax"> The L-stack</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">[26]; </span><span class="comment-syntax"> emission level at start of block</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> block_nesting serves at stack pointer here</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Push initial reason onto the R-stack</span><span class="named-paragraph-number">2.1.6.1.2.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="3-cdp.html#SP2_1_6_1_2_3" class="named-paragraph-link"><span class="named-paragraph">Compile the proposition into a search algorithm</span><span class="named-paragraph-number">2.1.6.1.2.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">Q_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_4" class="named-paragraph-link"><span class="named-paragraph">Pop the Q-stack</span><span class="named-paragraph-number">2.1.6.1.2.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"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_5" class="named-paragraph-link"><span class="named-paragraph">Pop the C-stack</span><span class="named-paragraph-number">2.1.6.1.2.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="3-cdp.html#SP2_1_6_1_2_2" class="named-paragraph-link"><span class="named-paragraph">Pop the R-stack</span><span class="named-paragraph-number">2.1.6.1.2.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">block_nesting</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="3-cdp.html#SP2_1_6_1_2_6" class="named-paragraph-link"><span class="named-paragraph">Close a block in the I6 code compiled to perform the search</span><span class="named-paragraph-number">2.1.6.1.2.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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.1. The R-stack. </b>This is a sort of "split goals into sub-goals" mechanism. In order to
|
|
determine
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if all but one of the closed doors are unlocked, ...</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">our main goal is to determine the truth of the "are unlocked" part. This
|
|
is reason <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">2.1.6.1.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="identifier-syntax">R_stack_reason</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</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_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</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="3-cdp.html#SP2_1_6_1_2">§2.1.6.1.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP_1" class="paragraph-anchor"></a><b>§.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 routine</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">.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">R_stack_reason</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</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_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</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="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2" class="paragraph-anchor"></a><b>§2.1.6.1.2.2. </b>The R-stack is then popped when the goal is accomplished (or rather, when
|
|
the I6 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 — 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">2.1.6.1.2.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">R_sp</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 underflow"</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_reason</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">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FILTER_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in CONDITION search</span><span class="named-paragraph-number">2.1.6.1.2.2.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="3-cdp.html#SP2_1_6_1_2_2_6" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in EXTREMAL search</span><span class="named-paragraph-number">2.1.6.1.2.2.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">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_7" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in LOOP search</span><span class="named-paragraph-number">2.1.6.1.2.2.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">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in NUMBER search</span><span class="named-paragraph-number">2.1.6.1.2.2.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="3-cdp.html#SP2_1_6_1_2_2_3" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in LIST search</span><span class="named-paragraph-number">2.1.6.1.2.2.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="3-cdp.html#SP2_1_6_1_2_2_5" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in TOTAL search</span><span class="named-paragraph-number">2.1.6.1.2.2.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">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_4" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in RANDOM search</span><span class="named-paragraph-number">2.1.6.1.2.2.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="3-cdp.html#SP2_1_6_1_2">§2.1.6.1.2</a>, <a href="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3" class="paragraph-anchor"></a><b>§2.1.6.1.2.3. Compiling the search. </b>In the following we run through the proposition from left to right, compiling
|
|
I6 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">2.1.6.1.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="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 </span><span class="extract"><span class="extract-syntax">CALLED</span></span><span class="comment-syntax"> atoms have been 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">-></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="3-cdp.html#SP2_1_6_1_2_3_3" 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">2.1.6.1.2.3.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] = (</span><span class="identifier-syntax">R_stack_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1])?</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="3-cdp.html#SP2_1_6_1_2_3_3" 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">2.1.6.1.2.3.3</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_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] == </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">-></span><span class="identifier-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="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_3_7" class="named-paragraph-link"><span class="named-paragraph">Push the Q-stack</span><span class="named-paragraph-number">2.1.6.1.2.3.7</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_3_5" class="named-paragraph-link"><span class="named-paragraph">Compile a loop through possible values of the variable quantified</span><span class="named-paragraph-number">2.1.6.1.2.3.5</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="3-cdp.html#SP2_1_6_1_2_3_3" 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">2.1.6.1.2.3.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP_1" class="named-paragraph-link"><span class="named-paragraph">Push domain-opening onto the R-stack</span><span class="named-paragraph-number">.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="3-cdp.html#SP2_1_6_1_2_3_3" 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">2.1.6.1.2.3.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2" class="named-paragraph-link"><span class="named-paragraph">Pop the R-stack</span><span class="named-paragraph-number">2.1.6.1.2.2</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="3-cdp.html#SP2_1_6_1_2_3_8" class="named-paragraph-link"><span class="named-paragraph">Push the C-stack</span><span class="named-paragraph-number">2.1.6.1.2.3.8</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_reason</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] == </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="3-cdp.html#SP2_1_6_1_2_3_4" class="named-paragraph-link"><span class="named-paragraph">Compile code to force the atom</span><span class="named-paragraph-number">2.1.6.1.2.3.4</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">++ > </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">-></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">) && (</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">-></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">-></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="3-cdp.html#SP2_1_6_1_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Compile code to test the atom</span><span class="named-paragraph-number">2.1.6.1.2.3.2</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="3-cdp.html#SP2_1_6_1_2_3_3" 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">2.1.6.1.2.3.3</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2">§2.1.6.1.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.1. Predicate runs and their negations. </b>Or, cheating Professor de Morgan.
|
|
</p>
|
|
|
|
<p class="commentary">If we have a run of predicate-like atoms — say X, Y, Z — 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 && Y && 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="SP2_1_6_1_2_3_2" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.2. </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">2.1.6.1.2.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">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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="3-ca.html#SP3" class="function-link"><span class="function-syntax">Atoms::Compile::emit</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><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_3" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.3. </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">2.1.6.1.2.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><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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> > </span><span class="constant-syntax">1</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_2_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the I6 code compiled to perform the search, if variant</span><span class="named-paragraph-number">2.1.6.1.2.3.3.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="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a> (five times).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_4" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.4. </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 <span class="extract"><span class="extract-syntax">Atoms::Compile::compile</span></span>.
|
|
</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.)
|
|
</p>
|
|
|
|
<p class="commentary">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">2.1.6.1.2.3.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="3-ca.html#SP3" class="function-link"><span class="function-syntax">Atoms::Compile::emit</span></a><span class="plain-syntax">((</span><span class="identifier-syntax">R_stack_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1])?</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><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_5" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.5. 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">and note that execution reaches the start of the loop body once for each
|
|
possible choice of \(v\), as required by the Invariant — indeed the Invariant
|
|
pretty much requires that this is what we compile.
|
|
</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">2.1.6.1.2.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level_back_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><a href="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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">-></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">-></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_reason</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] == </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="3-cdp.html#SP2_1_6_1_2_3_5_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the I6 code compiled to perform the search</span><span class="named-paragraph-number">2.1.6.1.2.3.5.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_6" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.6. </b>Generalised quantifiers — "at least three", "all but four", and
|
|
so on — 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 --> DOMAIN_OPEN --> psi --> DOMAIN_CLOSE --> 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="SP2_1_6_1_2_3_7" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.7. </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 — 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 — e.g.,
|
|
only doors, not all objects — 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">2.1.6.1.2.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">R_stack_reason</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] == </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="3-cdp.html#SP2_1_6_1_2_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Handle "not exists" as "for all not"</span><span class="named-paragraph-number">2.1.6.1.2.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack_quantifier</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</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_parameter</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</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_block_nesting</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">block_nesting</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack_C_stack_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_7_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.7.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">2.1.6.1.2.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="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_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1] = (</span><span class="identifier-syntax">R_stack_parity</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1])?</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="3-cdp.html#SP2_1_6_1_2_3_7">§2.1.6.1.2.3.7</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_4" class="paragraph-anchor"></a><b>§2.1.6.1.2.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 --> DOMAIN_OPEN --> psi --> DOMAIN_CLOSE --> 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 I6
|
|
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 routine: 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">2.1.6.1.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="identifier-syntax">Q_sp</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 underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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"> > </span><span class="identifier-syntax">Q_stack_C_stack_level</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="3-cdp.html#SP2_1_6_1_2_5" class="named-paragraph-link"><span class="named-paragraph">Pop the C-stack</span><span class="named-paragraph-number">2.1.6.1.2.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">block_nesting</span><span class="plain-syntax"> > </span><span class="identifier-syntax">Q_stack_block_nesting</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="3-cdp.html#SP2_1_6_1_2_6" class="named-paragraph-link"><span class="named-paragraph">Close a block in the I6 code compiled to perform the search</span><span class="named-paragraph-number">2.1.6.1.2.6</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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_quantifier</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">], </span><span class="identifier-syntax">Q_stack_parameter</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</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="3-cdp.html#SP2_1_6_1_2_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the I6 code compiled to perform the search, if variant</span><span class="named-paragraph-number">2.1.6.1.2.3.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2">§2.1.6.1.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_8" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.8. The C-stack. </b>When a CALLED atom in the proposition gives a name to a variable, we have to
|
|
transcribe that to the <span class="extract"><span class="extract-syntax">deferred_calling_list</span></span> for the benefit of the code
|
|
calling this proposition routine. 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">2.1.6.1.2.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">C_stack_term</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">C_stack_index</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</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="3-cdp.html#SP2_1_6_1_2_3">§2.1.6.1.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_5" class="paragraph-anchor"></a><b>§2.1.6.1.2.5. </b>When does the compiled search code record values into <span class="extract"><span class="extract-syntax">deferred_calling_list</span></span>?
|
|
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">2.1.6.1.2.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">C_sp</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 underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">LOOKUPREF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">DEFERRED_CALLING_LIST_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">C_stack_index</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Terms::emit</span><span class="plain-syntax">(</span><span class="identifier-syntax">C_stack_term</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2">§2.1.6.1.2</a>, <a href="3-cdp.html#SP2_1_6_1_2_4">§2.1.6.1.2.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_5_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.5.1. </b>That just leaves the blocking, which follows the One True Brace Style. Thus:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open a block in the I6 code compiled to perform the search</span><span class="named-paragraph-number">2.1.6.1.2.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="identifier-syntax">L_stack_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">block_nesting</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">block_nesting</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_3_5">§2.1.6.1.2.3.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_3_3_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.3.3.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 I6 code compiled to perform the search, if variant</span><span class="named-paragraph-number">2.1.6.1.2.3.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">L_stack_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">block_nesting</span><span class="plain-syntax">] = </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">())-1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">block_nesting</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_3_3">§2.1.6.1.2.3.3</a>, <a href="3-cdp.html#SP2_1_6_1_2_4">§2.1.6.1.2.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_6" class="paragraph-anchor"></a><b>§2.1.6.1.2.6. </b>and:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Close a block in the I6 code compiled to perform the search</span><span class="named-paragraph-number">2.1.6.1.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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()) > </span><span class="identifier-syntax">L_stack_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">block_nesting</span><span class="plain-syntax">-1]) </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">block_nesting</span><span class="plain-syntax">--;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2">§2.1.6.1.2</a>, <a href="3-cdp.html#SP2_1_6_1_2_4">§2.1.6.1.2.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_5_1" class="paragraph-anchor"></a><b>§2.1.5.1. 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> routine, 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 I6 locals needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">2.1.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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_routine</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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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">-></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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_internal_local_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="3-cdp.html#SP2_1_5">§2.1.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_5_2" class="paragraph-anchor"></a><b>§2.1.5.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the I6 call parameters needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">2.1.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">if</span><span class="plain-syntax"> ((!</span><span class="identifier-syntax">multipurpose_routine</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_named_call_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="2-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_named_call_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="3-cdp.html#SP2_1_5">§2.1.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_3" class="paragraph-anchor"></a><b>§2.1.6.1.3. 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">2.1.6.1.3</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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.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">2.1.6.1.2.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="identifier-syntax">Produce::rtrue</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_4" class="paragraph-anchor"></a><b>§2.1.6.1.4. </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">2.1.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="identifier-syntax">Produce::rfalse</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_5" class="paragraph-anchor"></a><b>§2.1.6.1.5. 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 I6 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">2.1.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><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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="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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_2" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.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 I6, 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">2.1.6.1.2.2.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">2.1.6.1.2.2.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_2_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.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">2.1.6.1.2.2.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">Produce::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::lab</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2_2">§2.1.6.1.2.2.2</a>, <a href="3-cdp.html#SP2_1_6_1_2_2_3">§2.1.6.1.2.2.3</a>, <a href="3-cdp.html#SP2_1_6_1_2_2_4">§2.1.6.1.2.2.4</a>, <a href="3-cdp.html#SP2_1_6_1_2_2_5">§2.1.6.1.2.2.5</a>, <a href="3-cdp.html#SP2_1_6_1_17">§2.1.6.1.17</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_6" class="paragraph-anchor"></a><b>§2.1.6.1.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Place next outer loop label</span><span class="named-paragraph-number">2.1.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="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">Produce::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::place_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_7" class="paragraph-anchor"></a><b>§2.1.6.1.7. </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 routine — which
|
|
is what we do for multipurpose deferred propositions — 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">2.1.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_8" class="paragraph-anchor"></a><b>§2.1.6.1.8. 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">2.1.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="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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="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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_3" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.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 I6, 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">2.1.6.1.2.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="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">8</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">2.1.6.1.2.2.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_9" class="paragraph-anchor"></a><b>§2.1.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 routine — which
|
|
is what we do for multipurpose deferred propositions — 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">2.1.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">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_10" class="paragraph-anchor"></a><b>§2.1.6.1.10. 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 I6 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">2.1.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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="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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_4" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.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">2.1.6.1.2.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="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">2.1.6.1.2.2.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_11" class="paragraph-anchor"></a><b>§2.1.6.1.11. </b>We return <span class="extract"><span class="extract-syntax">nothing</span></span> — the non-object — 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 — 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">2.1.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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_nothing</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_12" class="paragraph-anchor"></a><b>§2.1.6.1.12. 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">2.1.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">proposition</span><span class="plain-syntax"> = </span><a href="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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="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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_5" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.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 — when its identity will be found in the I6 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">2.1.6.1.2.2.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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_routine</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">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">-></span><span class="element-syntax">defn_ref</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">2.1.6.1.2.2.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_13" class="paragraph-anchor"></a><b>§2.1.6.1.13. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after TOTAL search</span><span class="named-paragraph-number">2.1.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_14" class="paragraph-anchor"></a><b>§2.1.6.1.14. 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 routine
|
|
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">2.1.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_routine</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">PROPERTY_LOOP_SIGN_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">MIN_NEGATIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">MAX_POSITIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">-></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">, &</span><span class="identifier-syntax">def_prn</span><span class="plain-syntax">, &</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">MIN_NEGATIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">MAX_POSITIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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="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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_6" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.6. </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">2.1.6.1.2.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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_routine</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">PROPERTY_LOOP_SIGN_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">2.1.6.1.2.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_2_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">2.1.6.1.2.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">2.1.6.1.2.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_2_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">2.1.6.1.2.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">2.1.6.1.2.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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="3-cdp.html#SP2_1_6_1_2_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">2.1.6.1.2.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_6_1" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.6.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">2.1.6.1.2.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="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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_routine</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">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">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">def_prn</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2_6">§2.1.6.1.2.2.6</a> (6 times).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_15" class="paragraph-anchor"></a><b>§2.1.6.1.15. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after EXTREMAL search</span><span class="named-paragraph-number">2.1.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_16" class="paragraph-anchor"></a><b>§2.1.6.1.16. 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="SP2_1_6_1_17" class="paragraph-anchor"></a><b>§2.1.6.1.17. </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. (The trick actually
|
|
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, doesn't forbid this. The designer of I6 has learned his
|
|
lesson, though: I7 has no goto or jump instruction, and I7 loops can be
|
|
proved to be entered and exited cleanly.)
|
|
</p>
|
|
|
|
<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">2.1.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">2.1.6.1.2.2.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cdp.html#SP2_1_6_1_2_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">2.1.6.1.2.2.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="3-cdp.html#SP5" class="function-link"><span class="function-syntax">Propositions::Deferred::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="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="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_2_2_7" class="paragraph-anchor"></a><b>§2.1.6.1.2.2.7. </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">2.1.6.1.2.2.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">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1_2_2">§2.1.6.1.2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_6_1_18" class="paragraph-anchor"></a><b>§2.1.6.1.18. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after LOOP search</span><span class="named-paragraph-number">2.1.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="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</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">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_nothing</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-cdp.html#SP2_1_6_1">§2.1.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. Compiling loop headers. </b>The final task of this entire chapter is to compile an I6 loop header which
|
|
causes a given variable \(v\) to range through a domain set \(D\) — 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. Most
|
|
optimisations aren't worth the risk in added complexity — but these are.
|
|
</p>
|
|
|
|
<p class="commentary">Loops through kinds of value are not in general optimisable. The problem cases
|
|
involve loops through objects. Consider:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if everyone in the Dining Room can see an animal, ...</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Code like this will 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 aren't 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="SP4" class="paragraph-anchor"></a><b>§4. </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) 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) 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 each 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.
|
|
</p>
|
|
|
|
<p class="commentary">Case (1) is called "kind optimisation"; case (2), "parent
|
|
optimisation", because the prototype case is \(R\) being containment — we
|
|
exploit that the object-tree parent of \(v\) is known, and that I6 has a fast
|
|
form of <span class="extract"><span class="extract-syntax">objectloop</span></span> to visit the children of a given node in the object
|
|
tree. Case (2) has to be avoided 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 loop-compiler takes 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>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>So here is the code. We write an I6 schema for the loop into <span class="extract"><span class="extract-syntax">loop_schema</span></span>,
|
|
then expand it into the output.
|
|
</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">Propositions::Deferred::compile_loop_header</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">Propositions::Deferred::compile_loop_header</span></span>:<br/><a href="3-cdp.html#SP2_1_6_1_2_3_5">§2.1.6.1.2.3.5</a>, <a href="3-cdp.html#SP2_1_6_1_5">§2.1.6.1.5</a>, <a href="3-cdp.html#SP2_1_6_1_8">§2.1.6.1.8</a>, <a href="3-cdp.html#SP2_1_6_1_10">§2.1.6.1.10</a>, <a href="3-cdp.html#SP2_1_6_1_12">§2.1.6.1.12</a>, <a href="3-cdp.html#SP2_1_6_1_14">§2.1.6.1.14</a>, <a href="3-cdp.html#SP2_1_6_1_17">§2.1.6.1.17</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">(&</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="3-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">) && (</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="3-dtd.html#SP24" class="function-link"><span class="function-syntax">Calculus::Deferrals::write_loop_schema</span></a><span class="plain-syntax">(&</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">-></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">-></span><span class="element-syntax">rtp_iname</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">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">ppd_package</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Calculus::Schemas::modify</span><span class="plain-syntax">(&</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">-></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="3-efs.html#SP1" class="function-link"><span class="function-syntax">EmitSchemas::emit_expand_from_terms</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, &</span><span class="identifier-syntax">var_term</span><span class="plain-syntax">, &</span><span class="identifier-syntax">second_term</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">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>§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 --> DOMAIN_OPEN --> psi --> DOMAIN_CLOSE --> ...</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">-></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">-></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">-></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">-></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"> < </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"> < </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"> > </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="3-cdp.html#SP5_1_1" class="named-paragraph-link"><span class="named-paragraph">Scan $\psi$, 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="3-cdp.html#SP5">§5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5_1_1" class="paragraph-anchor"></a><b>§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 $\psi$, 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">)) && (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></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">) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">PREDICATE_ATOM</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></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="3-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="3-cdp.html#SP5_1">§5.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5_1_1_1" class="paragraph-anchor"></a><b>§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">-></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"><=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">-></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">) && (</span><span class="identifier-syntax">pf</span><span class="plain-syntax">-></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">) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">BinaryPredicates::write_optimised_loop_schema</span><span class="plain-syntax">(&</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="identifier-syntax">pf</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">-></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">-></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">BinaryPredicates::write_optimised_loop_schema</span><span class="plain-syntax">(&</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">-></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="3-cdp.html#SP5_1_1">§5.1.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>And that 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="3-cad.html">❮</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-lv.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresssection"><a href="3-cfs.html">cfs</a></li><li class="progresssection"><a href="3-efs.html">efs</a></li><li class="progresssection"><a href="3-ca.html">ca</a></li><li class="progresssection"><a href="3-dtd.html">dtd</a></li><li class="progresssection"><a href="3-cad.html">cad</a></li><li class="progresscurrent">cdp</li><li class="progresschapter"><a href="4-inv.html">4</a></li><li class="progressnext"><a href="4-inv.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|