mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
2204 lines
324 KiB
HTML
2204 lines
324 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Compile Deferred Propositions</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
|
|
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
|
|
|
|
<script src="../docs-assets/Bigfoot.js"></script>
|
|
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Compile Deferred Propositions' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">imperative</a></li><li><a href="index.html#4">Chapter 4: Propositions</a></li><li><b>Compile Deferred Propositions</b></li></ul></div>
|
|
<p class="purpose">To compile the Inter functions needed to perform the tests or tasks deferred as being too difficult in their original contexts.</p>
|
|
|
|
<ul class="toc"><li><a href="4-cdp.html#SP1">§1. Comment</a></li><li><a href="4-cdp.html#SP2">§2. Preliminaries</a></li><li><a href="4-cdp.html#SP3_6_1_1">§3.6.1.1. The Search</a></li><li><a href="4-cdp.html#SP3_6_1_4_1">§3.6.1.4.1. The R-stack</a></li><li><a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2. Compiling the search</a></li><li><a href="4-cdp.html#SP3_6_1_4_2_2">§3.6.1.4.2.2. Predicate runs and their negations</a></li><li><a href="4-cdp.html#SP3_6_1_4_2_6">§3.6.1.4.2.6. Quantifiers and the Q-stack</a></li><li><a href="4-cdp.html#SP3_6_1_4_2_10">§3.6.1.4.2.10. The C-stack</a></li><li><a href="4-cdp.html#SP3_5_3">§3.5.3. Adaptations</a></li><li><a href="4-cdp.html#SP3_6_1_5">§3.6.1.5. Adaptation to CONDITION</a></li><li><a href="4-cdp.html#SP3_6_1_7">§3.6.1.7. Adaptation to NUMBER</a></li><li><a href="4-cdp.html#SP3_6_1_10">§3.6.1.10. Adaptation to LIST</a></li><li><a href="4-cdp.html#SP3_6_1_12">§3.6.1.12. Adaptation to RANDOM</a></li><li><a href="4-cdp.html#SP3_6_1_14">§3.6.1.14. Adaptation to TOTAL</a></li><li><a href="4-cdp.html#SP3_6_1_18">§3.6.1.18. Adaptation to EXTREMAL</a></li><li><a href="4-cdp.html#SP3_6_1_20">§3.6.1.20. Adaptation to LOOP</a></li><li><a href="4-cdp.html#SP4">§4. 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 Inter comment noting the reason for a deferral.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">DeferredPropositions::compile_comment_about_deferral_reason</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compile_comment_about_deferral_reason</span></span>:<br/><a href="4-cdp.html#SP3_6">§3.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"True or false?"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Force this to be true via 'now':"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find the extremal x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find next x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Construct a list of x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"How many x satisfy this?"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find a total property value over all x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find a total real property value over all x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Find a random x satisfying:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MULTIPURPOSE_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Abstraction for set of x such that:"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Unknown proposition deferral reason"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Preliminaries. </b>Propositions are deferred for diverse reasons: see <a href="4-dtd.html" class="internal">Deciding to Defer</a>. Here
|
|
we take our medicine, and actually compile those deferred propositions into
|
|
functions. This has to be done by an agent because funny things can happen
|
|
when we compile: we can create new text substitutions which create routines
|
|
which... and so on. (See <a href="../core-module/1-htc.html" class="internal">How To Compile (in core)</a>.)
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">DeferredPropositions::compilation_agent</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compilation_agent</span></span>:<br/>Deciding to Defer - <a href="4-dtd.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">compilation_subtask</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_pcalc_prop_deferral</span><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">-></span><span class="identifier-syntax">data</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-cdp.html#SP3" class="function-link"><span class="function-syntax">DeferredPropositions::compile</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>The basic structure of a proposition function is the same for all of the
|
|
various reasons, but with considerable variations affecting (mainly) the
|
|
initial setup and the returned value.
|
|
</p>
|
|
|
|
<p class="commentary">Note that the unchecked array bounds of 26 are safe here because propositions
|
|
may only use 26 different variables at most (<span class="extract"><span class="extract-syntax">x</span></span>, <span class="extract"><span class="extract-syntax">y</span></span>, <span class="extract"><span class="extract-syntax">z</span></span>, <span class="extract"><span class="extract-syntax">a</span></span>, ..., <span class="extract"><span class="extract-syntax">w</span></span>). Only
|
|
in very contrived circumstances are there ever more than three quantifiers, so
|
|
this is plenty large enough:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">DeferredPropositions::compile</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compile</span></span>:<br/><a href="4-cdp.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ct_locals_problem_thrown</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">negated_quantifier_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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_function</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 compilers</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reason_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[26], *</span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[26];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[26];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax">], *</span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_QC_VARIABLES</span><span class="plain-syntax">];</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">list_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">selection_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">strong_kind_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="constant-syntax">MULTIPURPOSE_DEFER</span><span class="plain-syntax">+1];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">r</span><span class="plain-syntax"> < </span><span class="constant-syntax">MULTIPURPOSE_DEFER</span><span class="plain-syntax">+1; </span><span class="identifier-syntax">r</span><span class="plain-syntax">++) </span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Simplify the proposition by flipping negated quantifiers, if possible</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">PREDICATE_CALCULUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling %n as deferred proposition: %d: reason %d: $D\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">ppd_iname</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><a href="3-fnc.html#SP2" class="function-link"><span class="function-syntax">Functions::begin</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">ppd_iname</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Declare the Inter local variables which will be needed by this deferral function</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6" class="named-paragraph-link"><span class="named-paragraph">Compile the code inside this deferral function</span><span class="named-paragraph-number">3.6</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if the table-lookup locals were needed</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if a negated quantifier was needed</span><span class="named-paragraph-number">3.4</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="3-fnc.html#SP6" class="function-link"><span class="function-syntax">Functions::end</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">save</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">rtp_iname</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Compile the constant origin text for run-time problem use</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>§3.1. </b>We compile the following only in cases where it seems possible that a
|
|
run-time problem message may be needed; compiling it for every deferred
|
|
proposition would be wasteful of space in the Z-machine.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the constant origin text for run-time problem use</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">COTT</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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::text_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="4-cdp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>§3.2. </b>Just in case this hasn't already been done:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Simplify the proposition by flipping negated quantifiers, if possible</span><span class="named-paragraph-number">3.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">changed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Simplifications::negated_determiners</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, &</span><span class="identifier-syntax">changed</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">changed</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">PREDICATE_CALCULUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Simplifications::negated_determiners: $D\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>§3.3. </b>While unfortunate in a way, this is for the best, because a successful match
|
|
on a condition looking up a table would record the table and row in local
|
|
variables within the deferred proposition: they would then be wrong in the
|
|
calling function, where they are needed.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if the table-lookup locals were needed</span><span class="named-paragraph-number">3.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::are_we_using_table_lookup</span></a><span class="plain-syntax">()) && (!</span><span class="identifier-syntax">ct_locals_problem_thrown</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ct_locals_problem_thrown</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CantLookUpTableInDeferred</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"I am not able to look up table entries in this complicated condition"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"which seems to involve making a potentially large number of checks in "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"rather few words (and may perhaps result from a misunderstanding such as "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"writing the name of a kind where an individual object is intended?)."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_4" class="paragraph-anchor"></a><b>§3.4. </b>This looks like a horrible restriction, but in fact propositions are built
|
|
and simplified in such a way that it never bites. (Quantifiers are always
|
|
moved outside of negation where possible, and it is almost always possible.)
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if a negated quantifier was needed</span><span class="named-paragraph-number">3.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated_quantifier_found</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this involves a very complicated negative thought"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"which I'm not able to untangle. Perhaps you could rephrase this more simply, "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"or split it into more than one sentence?"</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_5" class="paragraph-anchor"></a><b>§3.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the Inter local variables which will be needed by this deferral function</span><span class="named-paragraph-number">3.5</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"reason"</span><span class="plain-syntax">); </span><span class="comment-syntax"> no cinders exist here</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><a href="4-cad.html#SP5" class="function-link"><span class="function-syntax">Cinders::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">); </span><span class="comment-syntax"> no reason code needed, function does one thing</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_4" class="named-paragraph-link"><span class="named-paragraph">Declare the Inter call parameters needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_1" class="named-paragraph-link"><span class="named-paragraph">Declare locals corresponding to predicate calculus variables</span><span class="named-paragraph-number">3.5.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_2" class="named-paragraph-link"><span class="named-paragraph">Declare one pair of locals for each quantifier</span><span class="named-paragraph-number">3.5.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_5_3" class="named-paragraph-link"><span class="named-paragraph">Declare the Inter locals needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.3</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_5_1" class="paragraph-anchor"></a><b>§3.5.1. </b>If the proposition uses <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span>, we will define locals called <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span>
|
|
to hold their current values, and so on.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare locals corresponding to predicate calculus variables</span><span class="named-paragraph-number">3.5.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">var_states</span><span class="plain-syntax">[26];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Binding::determine_status</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_states</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax"><26; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var_states</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] != </span><span class="identifier-syntax">UNUSED_VST</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">pcalc_vars</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">, </span><span class="string-syntax">"_ix"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter_var</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">§3.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_5_2" class="paragraph-anchor"></a><b>§3.5.2. </b>The first quantifier gets <span class="extract"><span class="extract-syntax">qcy_0</span></span>, <span class="extract"><span class="extract-syntax">qcn_0</span></span>; the second <span class="extract"><span class="extract-syntax">qcy_1</span></span>, <span class="extract"><span class="extract-syntax">qcn_1</span></span>;
|
|
and so on.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare one pair of locals for each quantifier</span><span class="named-paragraph-number">3.5.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></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="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">, </span><span class="string-syntax">"qcn_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">] = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">q_var</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">no_extras</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">§3.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6" class="paragraph-anchor"></a><b>§3.6. </b>A multipurpose function <span class="extract"><span class="extract-syntax">f(x)</span></span> has to test whether \(\phi(x)\) is true if \(x \geq 0\),
|
|
but if \(x < 0\) then it will be one of the <span class="extract"><span class="extract-syntax">*_DUSAGE</span></span> values, and we switch on which
|
|
it is. Each of those switch cases contains code for one of the possibilities;
|
|
whereas for a single-purpose function, we just compile the code for that single
|
|
possibility.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the code inside this deferral function</span><span class="named-paragraph-number">3.6</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="constant-syntax">CONDITION_DUSAGE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SWITCH_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">safety_copy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">use</span><span class="plain-syntax"> = </span><span class="constant-syntax">EXTREMAL_DUSAGE</span><span class="plain-syntax">; </span><span class="identifier-syntax">use</span><span class="plain-syntax"> <= </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">TOTAL_REAL_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">TOTAL_REAL_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DUSAGE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">EXTREMAL_DEFER</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">use</span><span class="plain-syntax"> == </span><span class="constant-syntax">TOTAL_REAL_DUSAGE</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">TargetVMs::supports_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">()) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">CASE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">use</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><a href="4-cdp.html#SP1" class="function-link"><span class="function-syntax">DeferredPropositions::compile_comment_about_deferral_reason</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1" class="named-paragraph-link"><span class="named-paragraph">Compile body of deferred proposition for the given reason</span><span class="named-paragraph-number">3.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">reason</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1" class="named-paragraph-link"><span class="named-paragraph">Compile body of deferred proposition for the given reason</span><span class="named-paragraph-number">3.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1" class="paragraph-anchor"></a><b>§3.6.1. </b>So from here on we compile code to handle a single function.
|
|
</p>
|
|
|
|
<p class="commentary">What these different cases have in common is that each is basically a search
|
|
of all possible values of the bound variables in the expression. There will
|
|
be some initialisation, something to do with each successfully found
|
|
combination, and eventually some winding-up code. For example, "number of..."
|
|
initialises by setting <span class="extract"><span class="extract-syntax">counter</span></span> to 0, on each success it performs <span class="extract"><span class="extract-syntax">counter++</span></span>,
|
|
and at the end of the search it performs <span class="extract"><span class="extract-syntax">return counter</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile body of deferred proposition for the given reason</span><span class="named-paragraph-number">3.6.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">def_prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">def_prn_sign</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">OL</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_5" class="named-paragraph-link"><span class="named-paragraph">Initialisation before CONDITION search</span><span class="named-paragraph-number">3.6.1.5</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_18" class="named-paragraph-link"><span class="named-paragraph">Initialisation before EXTREMAL search</span><span class="named-paragraph-number">3.6.1.18</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_21" class="named-paragraph-link"><span class="named-paragraph">Initialisation before LOOP search</span><span class="named-paragraph-number">3.6.1.21</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_7" class="named-paragraph-link"><span class="named-paragraph">Initialisation before NUMBER search</span><span class="named-paragraph-number">3.6.1.7</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_10" class="named-paragraph-link"><span class="named-paragraph">Initialisation before LIST search</span><span class="named-paragraph-number">3.6.1.10</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_14" class="named-paragraph-link"><span class="named-paragraph">Initialisation before TOTAL search</span><span class="named-paragraph-number">3.6.1.14</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_15" class="named-paragraph-link"><span class="named-paragraph">Initialisation before TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.15</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_12" class="named-paragraph-link"><span class="named-paragraph">Initialisation before RANDOM search</span><span class="named-paragraph-number">3.6.1.12</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4" class="named-paragraph-link"><span class="named-paragraph">Compile code to search for valid combinations of variables</span><span class="named-paragraph-number">3.6.1.4</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">reason</span><span class="plain-syntax"> != </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">reason</span><span class="plain-syntax"> != </span><span class="constant-syntax">CONDITION_DEFER</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_8" class="named-paragraph-link"><span class="named-paragraph">Place next outer loop label</span><span class="named-paragraph-number">3.6.1.8</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">() > </span><span class="identifier-syntax">OL</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_6" class="named-paragraph-link"><span class="named-paragraph">Winding-up after CONDITION search</span><span class="named-paragraph-number">3.6.1.6</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_19" class="named-paragraph-link"><span class="named-paragraph">Winding-up after EXTREMAL search</span><span class="named-paragraph-number">3.6.1.19</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_22" class="named-paragraph-link"><span class="named-paragraph">Winding-up after LOOP search</span><span class="named-paragraph-number">3.6.1.22</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_9" class="named-paragraph-link"><span class="named-paragraph">Winding-up after NUMBER search</span><span class="named-paragraph-number">3.6.1.9</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_11" class="named-paragraph-link"><span class="named-paragraph">Winding-up after LIST search</span><span class="named-paragraph-number">3.6.1.11</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_16" class="named-paragraph-link"><span class="named-paragraph">Winding-up after TOTAL search</span><span class="named-paragraph-number">3.6.1.16</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_17" class="named-paragraph-link"><span class="named-paragraph">Winding-up after TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.17</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_13" class="named-paragraph-link"><span class="named-paragraph">Winding-up after RANDOM search</span><span class="named-paragraph-number">3.6.1.13</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6">§3.6</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_1" class="paragraph-anchor"></a><b>§3.6.1.1. The Search. </b>We can now begin the real work. Given \(\phi\), we compile Inter code which
|
|
contains a magic position M (for "match") such that M is visited exactly
|
|
once for every combination of possible substitutions into the bound
|
|
variables such that \(\phi\) is true. For example,
|
|
$$ \exists x: {\it door}(x)\land{\it open}(x)\land \exists y: {\it room}(y)\land{\it in}(x, y) $$
|
|
might compile to code in the form:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> blah, blah, blah {</span>
|
|
<span class="plain-syntax"> M</span>
|
|
<span class="plain-syntax"> } rhubarb, rhubarb</span>
|
|
</pre>
|
|
<p class="commentary">such that execution reaches <span class="extract"><span class="extract-syntax">M</span></span> exactly once for each combination of open
|
|
door \(x\) and room \(y\) such that \(x\) is in \(y\). (Position <span class="extract"><span class="extract-syntax">M</span></span> is where we
|
|
will place the case-dependent code for what to do on a successful match.)
|
|
In the language of model theory, this is a loop over all interpretations
|
|
of the variables in which \(\phi\) is true.
|
|
</p>
|
|
|
|
<p class="commentary">The algorithm below is, so far as I know, original to Inform, and it is not
|
|
simple to prove correct, so the reader will excuse a fairly hefty amount of
|
|
commentary here.
|
|
</p>
|
|
|
|
<p class="commentary">Our basic method is to compile the proposition from left to right. If there
|
|
are \(k\) atoms in \(\phi\), then there are \(k+1\) positions between atoms,
|
|
counting the start and the end. We maintain the following:
|
|
</p>
|
|
|
|
<ul class="items"><li>● Invariant. Let \(\psi\) be any syntactically valid subproposition
|
|
of \(\phi\) (that is, a contiguous sequence of atoms from \(\psi\) which would
|
|
be a valid proposition in its own right). Then there are before and after
|
|
positions <span class="extract"><span class="extract-syntax">B</span></span> and <span class="extract"><span class="extract-syntax">A</span></span> in the compiled Inter code for searching \(\phi\) such that
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">A</span></span> cannot be reached except from <span class="extract"><span class="extract-syntax">B</span></span>, and
|
|
</li><li>(b) at execution time, on every occasion <span class="extract"><span class="extract-syntax">B</span></span> is reached, <span class="extract"><span class="extract-syntax">A</span></span> is then reached
|
|
exactly once for each combination of possible substitutions into the
|
|
\(\exists\)-bound variables of \(\psi\) such that \(\psi\) is then true.
|
|
</li></ul>
|
|
</li></ul>
|
|
<p class="commentary">In particular, in the case when \(\psi = \phi\), <span class="extract"><span class="extract-syntax">B</span></span> is the start of our
|
|
compiled Inter code (before anything is done) and <span class="extract"><span class="extract-syntax">A</span></span> is the magic match
|
|
position <span class="extract"><span class="extract-syntax">M</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_2" class="paragraph-anchor"></a><b>§3.6.1.2. </b>Lemma: If the Invariant holds for two adjacent syntactically valid
|
|
subpropositions \(\mu\) and \(\nu\), then it holds for the subproposition \(\mu\nu\).
|
|
</p>
|
|
|
|
<p class="commentary">Proof of lemma: There are now three positions in the code: <span class="extract"><span class="extract-syntax">B1</span></span>, before \(\mu\);
|
|
<span class="extract"><span class="extract-syntax">B2</span></span>, before \(\nu\), which is the same position as after \(\mu\); and <span class="extract"><span class="extract-syntax">A</span></span>, after
|
|
\(\nu\). Execution reaches <span class="extract"><span class="extract-syntax">B2</span></span> \(m\) times for each visit to <span class="extract"><span class="extract-syntax">B1</span></span>, where \(m\)
|
|
is the number of combinations of viable bound variable values in \(\mu\).
|
|
Execution reaches <span class="extract"><span class="extract-syntax">A</span></span> \(n\) times for each visit to <span class="extract"><span class="extract-syntax">B2</span></span>, where \(n\) is the
|
|
similar number for \(\nu\). Therefore execution reaches <span class="extract"><span class="extract-syntax">A</span></span> a total of \(nm\)
|
|
times for each visit to <span class="extract"><span class="extract-syntax">B1</span></span>, the product of the number of variable combinations
|
|
in \(\mu\) and \(\nu\), which is exactly the number of combinations in total.
|
|
</p>
|
|
|
|
<p class="commentary">Corollary: If the Invariant holds for subpropositions in each of
|
|
the following forms, then it will hold overall:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">Exists v</span></span>, for some variable \(v\), or <span class="extract"><span class="extract-syntax">Q v IN[ ... IN]</span></span>, for some quantifier other than \(\exists\).
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">NOT[ ... NOT]</span></span>.
|
|
</li><li>(c) Any single predicate-like atom.
|
|
</li></ul>
|
|
<p class="commentary">Proof of corollary: All valid subpropositions are concatenations of (a) to (c),
|
|
and we then apply the Lemma inductively.
|
|
</p>
|
|
|
|
<p class="commentary">It follows that if we can prove our algorithm maintains the invariant in
|
|
cases (a) to (c), we can be sure it will correctly construct code leading
|
|
to the match point <span class="extract"><span class="extract-syntax">M</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_3" class="paragraph-anchor"></a><b>§3.6.1.3. </b>We will make use of four stacks:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) The R-stack, which holds the current "reason": the goal being pursued
|
|
by the Inter code currently being compiled.
|
|
</li><li>(b) The Q-stack, which holds details of quantifiers being searched on.
|
|
</li><li>(c) The C-stack, which holds details of callings of variables.
|
|
</li><li>(d) The L-stack, which records hierarchical levels in the Inter code generated.
|
|
The current stack pointer <span class="extract"><span class="extract-syntax">L_sp</span></span> for this is equivalent to the depth of nesting
|
|
of the Inter code being generated.
|
|
</li></ul>
|
|
<p class="commentary">Each stack begins empty: we want to be absolutely sure that this algorithm
|
|
behaves as expected, so internal errors are thrown if any stack underflows,
|
|
overflows, or is other than empty again at the end. The maximum capacity in each
|
|
case is tied either to the number of distinct predicate calculus variables, or
|
|
the number of quantifiers, and in either case is at worst 26. But the R-stack
|
|
potentially needs one more slot to hold the outermost reason, so we'll just
|
|
give them all a capacity of 27.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">Q_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">C_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax"> </span><span class="constant-syntax">27</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">r_stack_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">; </span><span class="comment-syntax"> what task are we performing? A </span><span class="extract"><span class="extract-syntax">*_DEFER</span></span><span class="comment-syntax"> value</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parity</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">TRUE</span></span><span class="comment-syntax"> if we want a match, </span><span class="extract"><span class="extract-syntax">FALSE</span></span><span class="comment-syntax"> if we want no match</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">r_stack_data</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">q_stack_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quant</span><span class="plain-syntax">; </span><span class="comment-syntax"> which quantifier</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parameter</span><span class="plain-syntax">; </span><span class="comment-syntax"> its parameter, e.g., 9 for "more than nine"</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_stack_level</span><span class="plain-syntax">; </span><span class="comment-syntax"> at the point this occurs</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L_stack_level</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">existential</span><span class="plain-syntax">; </span><span class="comment-syntax"> just one solution is needed</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">q_stack_data</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">c_stack_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">term</span><span class="plain-syntax">; </span><span class="comment-syntax"> the term to which a calling is being given</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stash_index</span><span class="plain-syntax">; </span><span class="comment-syntax"> its index in the stash of callings</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">c_stack_data</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">l_stack_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">; </span><span class="comment-syntax"> Inter emission level at start of code block</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">l_stack_data</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure r_stack_data is accessed in 4/dtd and here.</li><li>The structure q_stack_data is private to this section.</li><li>The structure c_stack_data is private to this section.</li><li>The structure l_stack_data is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4" class="paragraph-anchor"></a><b>§3.6.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to search for valid combinations of variables</span><span class="named-paragraph-number">3.6.1.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">r_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">q_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">Q_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">c_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">C_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">l_stack_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax">]; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Push initial reason onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> we now begin compiling the search code</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2" class="named-paragraph-link"><span class="named-paragraph">Compile the proposition into a search algorithm</span><span class="named-paragraph-number">3.6.1.4.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_4" class="named-paragraph-link"><span class="named-paragraph">Pop the Q-stack</span><span class="named-paragraph-number">3.6.1.4.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_5" class="named-paragraph-link"><span class="named-paragraph">Pop the C-stack</span><span class="named-paragraph-number">3.6.1.4.5</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> we are now at the magic match point </span><span class="extract"><span class="extract-syntax">M</span></span><span class="comment-syntax"> in the search code</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3" class="named-paragraph-link"><span class="named-paragraph">Pop the R-stack</span><span class="named-paragraph-number">3.6.1.4.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_6" class="named-paragraph-link"><span class="named-paragraph">Pop the L-stack</span><span class="named-paragraph-number">3.6.1.4.6</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> we have now finished compiling the search code</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R-stack failure"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Q-stack failure"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"C-stack failure"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack failure"</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_1" class="paragraph-anchor"></a><b>§3.6.1.4.1. The R-stack. </b>This is a sort of "split goals into sub-goals" mechanism. In order to
|
|
determine, say, "if all but one of the closed doors are unlocked", the main
|
|
goal is to determine the truth of the "are unlocked" part. For that example,
|
|
<span class="extract"><span class="extract-syntax">reason</span></span> will be <span class="extract"><span class="extract-syntax">CONDITION_DEFER</span></span>, and it is pushed onto the R-stack at the
|
|
start of the compilation:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push initial reason onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R-stack overflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">reason</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reason</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">§3.6.1.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_1" class="paragraph-anchor"></a><b>§3.6.1.4.2.1. </b>But in order to work this out, we have to work out which doors are closed,
|
|
and this is a subgoal to which we give the pseudo-reason <span class="extract"><span class="extract-syntax">FILTER_DEFER</span></span>. We
|
|
push this new sub-goal onto the R-stack, leaving the original to be resumed
|
|
when we're done.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">FILTER_DEFER</span><span class="plain-syntax"> </span><span class="constant-syntax">10000</span><span class="plain-syntax"> </span><span class="comment-syntax"> pseudo-reason value used only inside this function</span>
|
|
</pre>
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push domain-opening onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">R_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R-stack overflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">reason</span><span class="plain-syntax"> = </span><span class="constant-syntax">FILTER_DEFER</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3" class="paragraph-anchor"></a><b>§3.6.1.4.3. </b>The R-stack is then popped when the goal is accomplished (or rather, when
|
|
the Inter code we are compiling has reached a point which will be executed when
|
|
its goal has been accomplished).
|
|
</p>
|
|
|
|
<p class="commentary">In the case of <span class="extract"><span class="extract-syntax">FILTER_DEFER</span></span>, when scanning domains of quantifiers, we increment
|
|
the count of the domain set size — the number of closed doors, in the above
|
|
example. (See below.)
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the R-stack</span><span class="named-paragraph-number">3.6.1.4.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"R stack underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">--;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">].</span><span class="element-syntax">reason</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FILTER_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Q stack underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">-1]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_ASSERTION_DEFER:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONDITION_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_1" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in CONDITION search</span><span class="named-paragraph-number">3.6.1.4.3.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in EXTREMAL search</span><span class="named-paragraph-number">3.6.1.4.3.7</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_DOMAIN_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_8" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in LOOP search</span><span class="named-paragraph-number">3.6.1.4.3.8</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in NUMBER search</span><span class="named-paragraph-number">3.6.1.4.3.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_3" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in LIST search</span><span class="named-paragraph-number">3.6.1.4.3.3</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_5" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in TOTAL search</span><span class="named-paragraph-number">3.6.1.4.3.5</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_6" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.4.3.6</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_4" class="named-paragraph-link"><span class="named-paragraph">Act on successful match in RANDOM search</span><span class="named-paragraph-number">3.6.1.4.3.4</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">§3.6.1.4</a>, <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2" class="paragraph-anchor"></a><b>§3.6.1.4.2. Compiling the search. </b>In the following we run through the proposition from left to right, compiling
|
|
Inter code as we go, but preserving the Invariant.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the proposition into a search algorithm</span><span class="named-paragraph-number">3.6.1.4.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_deferred_callings</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> how many callings found to date</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="identifier-syntax">element</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEGATION_OPEN_ATOM:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEGATION_CLOSE_ATOM:</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> reverse parity</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">QUANTIFIER_ATOM:</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">negated_quantifier_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">quant</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">param</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Atoms::get_quantification_parameter</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> == </span><span class="identifier-syntax">exists_quantifier</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_9" class="named-paragraph-link"><span class="named-paragraph">Mark the Q-stack to show an inner existential quantifier is in play</span><span class="named-paragraph-number">3.6.1.4.2.9</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_8" class="named-paragraph-link"><span class="named-paragraph">Push the Q-stack</span><span class="named-paragraph-number">3.6.1.4.2.8</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_6" class="named-paragraph-link"><span class="named-paragraph">Compile a loop through possible values of the variable quantified</span><span class="named-paragraph-number">3.6.1.4.2.6</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_OPEN_ATOM:</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_1" class="named-paragraph-link"><span class="named-paragraph">Push domain-opening onto the R-stack</span><span class="named-paragraph-number">3.6.1.4.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_CLOSE_ATOM:</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3" class="named-paragraph-link"><span class="named-paragraph">Pop the R-stack</span><span class="named-paragraph-number">3.6.1.4.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">CreationPredicates::is_calling_up_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_10" class="named-paragraph-link"><span class="named-paragraph">Push the C-stack</span><span class="named-paragraph-number">3.6.1.4.2.10</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_5" class="named-paragraph-link"><span class="named-paragraph">Compile code to force the atom</span><span class="named-paragraph-number">3.6.1.4.2.5</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_in_run</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax">++ > </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="4-cdp.html#SP3_6_1_4_2_3" class="named-paragraph-link"><span class="named-paragraph">Compile code to test the atom</span><span class="named-paragraph-number">3.6.1.4.2.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4" class="named-paragraph-link"><span class="named-paragraph">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">§3.6.1.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_2" class="paragraph-anchor"></a><b>§3.6.1.4.2.2. Predicate runs and their negations. </b>Or, cheating Professor de Morgan.
|
|
</p>
|
|
|
|
<p class="commentary">If we have a run of predicate-like atoms — 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="SP3_6_1_4_2_3" class="paragraph-anchor"></a><b>§3.6.1.4.2.3. </b>That means a little fancy footwork to start and finish the compound <span class="extract"><span class="extract-syntax">if</span></span>
|
|
statement properly:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to test the atom</span><span class="named-paragraph-number">3.6.1.4.2.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_in_run</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">NOT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">last_in_run</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-ca.html#SP1" class="function-link"><span class="function-syntax">CompileAtoms::code_to_perform</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">TEST_ATOM_TASK</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_4" class="paragraph-anchor"></a><b>§3.6.1.4.2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">End a run of predicate-like conditions, if one is under way</span><span class="named-paragraph-number">3.6.1.4.2.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> > </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">EmitCode::up</span><span class="plain-syntax">(); </span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax">--; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">(); }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">run_of_conditions</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the Inter code compiled to perform the search, if variant</span><span class="named-paragraph-number">3.6.1.4.2.4.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a> (five times).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_5" class="paragraph-anchor"></a><b>§3.6.1.4.2.5. </b>The <span class="extract"><span class="extract-syntax">NOW_ASSERTION_DEFER</span></span> reason is different from all of the others,
|
|
because rather than searching for a given situation it tries force it to
|
|
happen (or not to). Forcing rather than testing is easy here: we just supply
|
|
a different task when calling <a href="4-ca.html#SP1" class="internal">CompileAtoms::code_to_perform</a>.
|
|
</p>
|
|
|
|
<p class="commentary">In the negated case, we again cheat de Morgan, by falsifying \(\phi\) more
|
|
aggressively than we need: we force \(\lnot(X)\land\lnot(Y)\land\lnot(Z)\) to
|
|
be true, though strictly speaking it would be enough to falsify X alone.
|
|
(We do it that way for consistency with the same convention when asserting
|
|
about the model world.) But we don't need to consider runs of predicates for
|
|
that; we can take the atoms one at a time.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to force the atom</span><span class="named-paragraph-number">3.6.1.4.2.5</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="4-ca.html#SP1" class="function-link"><span class="function-syntax">CompileAtoms::code_to_perform</span></a><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax">)?</span><span class="identifier-syntax">NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_6" class="paragraph-anchor"></a><b>§3.6.1.4.2.6. Quantifiers and the Q-stack. </b>It remains to deal with quantifiers, and to show that the Invariant is
|
|
preserved by them. There are two cases: \(\exists\), and everything else.
|
|
</p>
|
|
|
|
<p class="commentary">The existence case is the easiest. Given \(\exists v: \psi(v)\) we compile
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> loop header for v to run through its domain set {</span>
|
|
<span class="plain-syntax"> ...</span>
|
|
</pre>
|
|
<p class="commentary">arranging that execution reaches the start of the loop body once for each
|
|
possible choice of \(v\), as required by the Invariant.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile a loop through possible values of the variable quantified</span><span class="named-paragraph-number">3.6.1.4.2.6</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level_back_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></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</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> != </span><span class="identifier-syntax">exists_quantifier</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_6_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the Inter code compiled to perform the search</span><span class="named-paragraph-number">3.6.1.4.2.6.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_7" class="paragraph-anchor"></a><b>§3.6.1.4.2.7. </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="SP3_6_1_4_2_8" class="paragraph-anchor"></a><b>§3.6.1.4.2.8. </b>The domain size and valid case counts are stored in locals called <span class="extract"><span class="extract-syntax">qcn_N</span></span>
|
|
and <span class="extract"><span class="extract-syntax">qcy_N</span></span> respectively, where <span class="extract"><span class="extract-syntax">N</span></span> is the index of the quantifier — 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">3.6.1.4.2.8</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">reason</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOW_ASSERTION_DEFER</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_8_1" class="named-paragraph-link"><span class="named-paragraph">Handle "not exists" as "for all not"</span><span class="named-paragraph-number">3.6.1.4.2.8.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">quant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">quant</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parameter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">param</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">L_stack_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">C_stack_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">existential</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_9" class="paragraph-anchor"></a><b>§3.6.1.4.2.9. </b>Existential quantifiers are not pushed to the Q-stack, because they are
|
|
by definition about finding the first solution, not counting solutions. But
|
|
we need to record their presence anyway:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Mark the Q-stack to show an inner existential quantifier is in play</span><span class="named-paragraph-number">3.6.1.4.2.9</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">existential</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_8_1" class="paragraph-anchor"></a><b>§3.6.1.4.2.8.1. </b>It is always true that \(\not\exists x: \psi(x)\) is equivalent to $\forall x:
|
|
\lnot(\phi(x))$, so the following seems pointless. We do this, in the case
|
|
of "now" only, in order to make \(\not\exists\) legal in a "now", which
|
|
it otherwise wouldn't be. Most quantifiers aren't, because they are too vague:
|
|
"now fewer than six doors are open", for instance, is not allowed. But we
|
|
do want to allow "now nobody likes Mr Wickham", say, which asserts
|
|
\(\not\exists x: {\it person}(x)\land{\it likes}(x, W)\).
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle "not exists" as "for all not"</span><span class="named-paragraph-number">3.6.1.4.2.8.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_exists_quantifier</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">R_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">R_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">parity</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">quant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">for_all_quantifier</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2_8">§3.6.1.4.2.8</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_4" class="paragraph-anchor"></a><b>§3.6.1.4.4. </b>To resume the narrative of what happens when we read:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> QUANTIFIER --> 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 Inter
|
|
code gets to the end of testing \(\theta\) then it must have found a valid
|
|
case: in the "at least three doors are unlocked" example, it will have
|
|
found an unlocked one among the doors making up the domain. We then need
|
|
to record any "called" values for later retrieval by whoever called
|
|
this proposition function: see below. That leaves just this part:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> if the counts are such that the quantifier is satisfied {</span>
|
|
<span class="plain-syntax"> ...</span>
|
|
</pre>
|
|
<p class="commentary">left to compile, and we will be done: execution will reach the <span class="extract"><span class="extract-syntax">...</span></span> if and
|
|
only if it is true at run-time that three or more of the doors is unlocked.
|
|
</p>
|
|
|
|
<p class="commentary">Thus this elaborate generalised-quantifier case satisfies the Invariant
|
|
because it transfers execution from before to <span class="extract"><span class="extract-syntax">...</span></span> either 0 times (if the
|
|
counts don't satisfy us), or once. Unlike in the \(\exists v\) case, it's
|
|
not a question of enumerating which \(v\) work and which do not; the whole
|
|
thing works, or doesn't, and is more like testing a single <span class="extract"><span class="extract-syntax">if</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the Q-stack</span><span class="named-paragraph-number">3.6.1.4.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Q stack underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_4_1" class="named-paragraph-link"><span class="named-paragraph">Count this as a success</span><span class="named-paragraph-number">3.6.1.4.4.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> > </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">C_stack_level</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_5" class="named-paragraph-link"><span class="named-paragraph">Pop the C-stack</span><span class="named-paragraph-number">3.6.1.4.5</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> > </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">L_stack_level</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_6" class="named-paragraph-link"><span class="named-paragraph">Pop the L-stack</span><span class="named-paragraph-number">3.6.1.4.6</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Quantifiers::emit_test</span><span class="plain-syntax">(</span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">quant</span><span class="plain-syntax">, </span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">parameter</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">], </span><span class="identifier-syntax">qcn_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_2_4_1" class="named-paragraph-link"><span class="named-paragraph">Open a block in the Inter code compiled to perform the search, if variant</span><span class="named-paragraph-number">3.6.1.4.2.4.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">§3.6.1.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_4_1" class="paragraph-anchor"></a><b>§3.6.1.4.4.1. </b>Note that if there is an existential quantifier inside the quantifier we
|
|
are counting solutions for, then we halt the search as soon as a solution is found;
|
|
we don't want to rack up <span class="extract"><span class="extract-syntax">qcy_s[Q_sp]</span></span> to artificially high levels by finding
|
|
multiple solutions. See test case <span class="extract"><span class="extract-syntax">CountInnerExistential</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Count this as a success</span><span class="named-paragraph-number">3.6.1.4.4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">qcy_s</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">Q_sp</span><span class="plain-syntax">].</span><span class="element-syntax">existential</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">BREAK_BIP</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_4">§3.6.1.4.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_10" class="paragraph-anchor"></a><b>§3.6.1.4.2.10. The C-stack. </b>When a CALLED atom in the proposition gives a name to a variable, we have to
|
|
transcribe that to the stash of callings for the benefit of the code
|
|
calling this proposition function. Each time we discover that a term \(t\) is
|
|
to be given a name, we stack it up. These are not always variables:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if a person (called the dupe) is in a dark room (called the lair), ...</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">gives names to \(x\) ("dupe") and \(f_{\it in}(x)\) ("lair"), because
|
|
simplification has eliminated the variable \(y\) which appears to be being
|
|
given a name.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push the C-stack</span><span class="named-paragraph-number">3.6.1.4.2.10</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">C_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"C-stack overflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">stash_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">no_deferred_callings</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2">§3.6.1.4.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_5" class="paragraph-anchor"></a><b>§3.6.1.4.5. </b>When does the compiled search code record values into the stash of callings?
|
|
In two situations:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) when a domain-search has successfully found a viable case for a quantifier,
|
|
the values of any variables called in that domain are recorded;
|
|
</li><li>(b) and otherwise the values of called variables are recorded just before
|
|
point <span class="extract"><span class="extract-syntax">M</span></span>, that is, immediately before acting on a successful match.
|
|
</li></ul>
|
|
<p class="commentary">For example, when reading:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if a person (called the dupe) is in a lighted room which is adjacent to exactly one dark room (called the lair), ...</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">the value of "dupe" is transferred just before <span class="extract"><span class="extract-syntax">M</span></span>, but the value of "lair"
|
|
is transferred as soon as a dark room is found. The code looks like this:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> set count of domain size to 1</span>
|
|
<span class="plain-syntax"> loop through domain (i.e., dark rooms adjacent to the person's location) {</span>
|
|
<span class="plain-syntax"> increment count of domain size</span>
|
|
<span class="plain-syntax"> record the lair value</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> if the count of domain size is 1 {</span>
|
|
<span class="plain-syntax"> record the dupe value</span>
|
|
<span class="plain-syntax"> M</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<p class="commentary">If we waited until point <span class="extract"><span class="extract-syntax">M</span></span> to record the lair value, it would have disappeared,
|
|
because <span class="extract"><span class="extract-syntax">M</span></span> is outside the loop which searches the domain of the "exactly one"
|
|
quantifier.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the C-stack</span><span class="named-paragraph-number">3.6.1.4.5</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"C stack underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::reference</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOOKUP_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="3-lp.html#SP5" class="function-link"><span class="function-syntax">LocalParking::callings</span></a><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">stash_index</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><a href="4-cs.html#SP5" class="function-link"><span class="function-syntax">CompileSchemas::compile_term</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">C_sp</span><span class="plain-syntax">].</span><span class="element-syntax">term</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">§3.6.1.4</a>, <a href="4-cdp.html#SP3_6_1_4_4">§3.6.1.4.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_6_1" class="paragraph-anchor"></a><b>§3.6.1.4.2.6.1. </b>Opening a block is the same thing as pushing to the L-stack:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open a block in the Inter code compiled to perform the search</span><span class="named-paragraph-number">3.6.1.4.2.6.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack overflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">].</span><span class="element-syntax">level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">level_back_to</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2_6">§3.6.1.4.2.6</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_2_4_1" class="paragraph-anchor"></a><b>§3.6.1.4.2.4.1. </b>Not for a loop body:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open a block in the Inter code compiled to perform the search, if variant</span><span class="named-paragraph-number">3.6.1.4.2.4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">L_STACK_CAPACITY</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack overflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">].</span><span class="element-syntax">level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">()-1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_2_4">§3.6.1.4.2.4</a>, <a href="4-cdp.html#SP3_6_1_4_4">§3.6.1.4.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_6" class="paragraph-anchor"></a><b>§3.6.1.4.6. </b>Close a block in the Inter code compiled to perform the search:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the L-stack</span><span class="named-paragraph-number">3.6.1.4.6</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"L-stack underflow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EmitCode::level</span><span class="plain-syntax">() > </span><span class="identifier-syntax">L_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">level</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">L_sp</span><span class="plain-syntax">--;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4">§3.6.1.4</a>, <a href="4-cdp.html#SP3_6_1_4_4">§3.6.1.4.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_5_3" class="paragraph-anchor"></a><b>§3.5.3. Adaptations. </b>That completes the general pattern of searching according to the proposition's
|
|
instructions. It remains to adapt it to different needs, by providing, in
|
|
each case, some setting-up code; some code to execute when a viable set
|
|
of variable values is found; and some winding-up code.
|
|
</p>
|
|
|
|
<p class="commentary">In some of the cases, additional local variables are needed within the
|
|
<span class="extract"><span class="extract-syntax">Prop_N</span></span> function, to keep track of counters or totals. These are they:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the Inter locals needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"selection"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">best_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best_with"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">reason</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NUMBER_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOM_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"selection"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TOTAL_REAL_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"counter"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">total_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"total"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTREMAL_DEFER:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">best_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"best_with"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">§3.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_5_4" class="paragraph-anchor"></a><b>§3.5.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare the Inter call parameters needed by adaptations to particular deferral cases</span><span class="named-paragraph-number">3.5.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((!</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) && (</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="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"list"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"strong_kind"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_5">§3.5</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_5" class="paragraph-anchor"></a><b>§3.6.1.5. Adaptation to CONDITION. </b>The first and simplest of our cases to understand: where \(\phi\) is a sentence,
|
|
with all variables bound, and we have to return <span class="extract"><span class="extract-syntax">true</span></span> if it is true and
|
|
<span class="extract"><span class="extract-syntax">false</span></span> if it is false. There is no initialisation:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before CONDITION search</span><span class="named-paragraph-number">3.6.1.5</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> ;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_1" class="paragraph-anchor"></a><b>§3.6.1.4.3.1. </b>As soon as we find any valid combination of the variables, we return <span class="extract"><span class="extract-syntax">true</span></span>:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in CONDITION search</span><span class="named-paragraph-number">3.6.1.4.3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::rtrue</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_6" class="paragraph-anchor"></a><b>§3.6.1.6. </b>So we only reach winding-up if every case failed, and then we return <span class="extract"><span class="extract-syntax">false</span></span>:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after CONDITION search</span><span class="named-paragraph-number">3.6.1.6</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::rfalse</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_7" class="paragraph-anchor"></a><b>§3.6.1.7. Adaptation to NUMBER. </b>In the remaining cases, \(\phi\) has variable \(x\) (only) left free, but the use
|
|
we want to make will be a loop over all objects \(x\), and we compile this
|
|
"outer loop" here: the loop opens in the initialisation code, closes in
|
|
the winding-up code, and therefore completely encloses the code generated
|
|
by the searching mechanism above.
|
|
</p>
|
|
|
|
<p class="commentary">In the first case, we want to count the number of \(x\) for which \(\phi(x)\)
|
|
is true. The local <span class="extract"><span class="extract-syntax">counter</span></span> holds the count so far; it starts out automatically
|
|
at 0, since all Inter locals do.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before NUMBER search</span><span class="named-paragraph-number">3.6.1.7</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_2" class="paragraph-anchor"></a><b>§3.6.1.4.3.2. </b>Recall that we get here for each possible way that \(\phi(x)\) could
|
|
be true, that is, once for each viable set of values of bound variables in
|
|
\(\phi\). But we only want to increment <span class="extract"><span class="extract-syntax">counter</span></span> once, so having done so, we
|
|
exit the searching code and continue the outer loop.
|
|
</p>
|
|
|
|
<p class="commentary">The <span class="extract"><span class="extract-syntax">jump</span></span> to a label is forced on us since Inter, unlike, say, Perl, has no
|
|
syntax to break or continue a loop other than the innermost one.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in NUMBER search</span><span class="named-paragraph-number">3.6.1.4.3.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_2_1" class="paragraph-anchor"></a><b>§3.6.1.4.3.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="string-syntax">".NextOuterLoop_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] = </span><span class="identifier-syntax">EmitCode::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">JUMP_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::lab</span><span class="plain-syntax">(</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3_2">§3.6.1.4.3.2</a>, <a href="4-cdp.html#SP3_6_1_4_3_3">§3.6.1.4.3.3</a>, <a href="4-cdp.html#SP3_6_1_4_3_4">§3.6.1.4.3.4</a>, <a href="4-cdp.html#SP3_6_1_4_3_5">§3.6.1.4.3.5</a>, <a href="4-cdp.html#SP3_6_1_4_3_6">§3.6.1.4.3.6</a>, <a href="4-cdp.html#SP3_6_1_21">§3.6.1.21</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_8" class="paragraph-anchor"></a><b>§3.6.1.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Place next outer loop label</span><span class="named-paragraph-number">3.6.1.8</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="string-syntax">".NextOuterLoop_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">] = </span><span class="identifier-syntax">EmitCode::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::place_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">NextOuterLoop_labels</span><span class="plain-syntax">[</span><span class="identifier-syntax">reason</span><span class="plain-syntax">]);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_9" class="paragraph-anchor"></a><b>§3.6.1.9. </b>The continue-outer-loop labels are marked with the reason number so that
|
|
if code is compiled for each reason in turn within a single function — 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">3.6.1.9</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_10" class="paragraph-anchor"></a><b>§3.6.1.10. Adaptation to LIST. </b>In the next case, we want to form the list of all \(x\) for which \(\phi(x)\)
|
|
is true. The local <span class="extract"><span class="extract-syntax">list</span></span> holds the list so far, and already exists.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before LIST search</span><span class="named-paragraph-number">3.6.1.10</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">BLKVALUEWRITE_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_ITEM_KOV_F_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">strong_kind_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_GETLENGTH_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_3" class="paragraph-anchor"></a><b>§3.6.1.4.3.3. </b>Recall that we get here for each possible way that \(\phi(x)\) could
|
|
be true, that is, once for each viable set of values of bound variables in
|
|
\(\phi\). But we only want to increment <span class="extract"><span class="extract-syntax">counter</span></span> once, so having done so, we
|
|
exit the searching code and continue the outer loop.
|
|
</p>
|
|
|
|
<p class="commentary">The <span class="extract"><span class="extract-syntax">jump</span></span> to a label is forced on us since Inter, unlike, say, Perl, has no
|
|
syntax to break or continue a loop other than the innermost one.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in LIST search</span><span class="named-paragraph-number">3.6.1.4.3.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(3);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(2);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(8);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_SETLENGTH_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">BLKVALUEWRITE_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">MINUS_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_ITEM_BASE_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_11" class="paragraph-anchor"></a><b>§3.6.1.11. </b>The continue-outer-loop labels are marked with the reason number so that
|
|
if code is compiled for each reason in turn within a single function — 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">3.6.1.11</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_SETLENGTH_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_12" class="paragraph-anchor"></a><b>§3.6.1.12. Adaptation to RANDOM. </b>To choose a random \(x\) such that \(\phi(x)\), we essentially run the same code
|
|
as for NUMBER searches, but twice over: first to count how many such \(x\) there
|
|
are, then to run through again to find the \(n\)th of these, where \(n\) is a
|
|
uniformly random number such that \(1\leq n\leq x\).
|
|
</p>
|
|
|
|
<p class="commentary">This avoids needing to store the full list of matches anywhere, which would
|
|
be impossible since (a) it's potentially a lot of storage and (b) it can
|
|
only safely live on the current stack frame, and Inter does not allow arrays
|
|
on the current stack frame (because of restrictions in the Z-machine).
|
|
This means that, on average, the compiled code takes 50\% longer to find
|
|
its random \(x\) than it ideally would, but we accept the trade-off.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before RANDOM search</span><span class="named-paragraph-number">3.6.1.12</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">((</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) -1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">WHILE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_true</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_4" class="paragraph-anchor"></a><b>§3.6.1.4.3.4. </b>Again we exit the searcher as soon as a match is found, since that guarantees
|
|
that \(\phi(x)\).
|
|
</p>
|
|
|
|
<p class="commentary">Note that we can only return here on the second pass, since <span class="extract"><span class="extract-syntax">selection</span></span> is \(-1\)
|
|
throughout the first pass, whereas <span class="extract"><span class="extract-syntax">counter</span></span> is non-negative.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in RANDOM search</span><span class="named-paragraph-number">3.6.1.4.3.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTINCREMENT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_13" class="paragraph-anchor"></a><b>§3.6.1.13. </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">3.6.1.13</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">OR_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_nothing</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RANDOM_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_14" class="paragraph-anchor"></a><b>§3.6.1.14. Adaptation to TOTAL. </b>Here the task is to sum the values of property \(P\) attached to each object
|
|
in the domain \(\lbrace x\mid \phi(x)\rbrace\).
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before TOTAL search</span><span class="named-paragraph-number">3.6.1.14</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_15" class="paragraph-anchor"></a><b>§3.6.1.15. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.15</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_5" class="paragraph-anchor"></a><b>§3.6.1.4.3.5. </b>The only wrinkle here is the way the compiled code knows which property it
|
|
should be totalling. If we know that ourselves, we can compile in a direct
|
|
reference. But if we are compiling a multipurpose deferred proposition, then
|
|
it might be used to total any property over the domain, and we won't know
|
|
which until runtime — when its identity will be found in the Inter variable
|
|
<span class="extract"><span class="extract-syntax">property_to_be_totalled</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in TOTAL search</span><span class="named-paragraph-number">3.6.1.4.3.5</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTKindIDs::weak_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">defn_ref</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTProperties::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_6" class="paragraph-anchor"></a><b>§3.6.1.4.3.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.4.3.6</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_PLUS_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTKindIDs::weak_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">defn_ref</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTProperties::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_16" class="paragraph-anchor"></a><b>§3.6.1.16. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after TOTAL search</span><span class="named-paragraph-number">3.6.1.16</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_17" class="paragraph-anchor"></a><b>§3.6.1.17. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after TOTAL REAL search</span><span class="named-paragraph-number">3.6.1.17</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_18" class="paragraph-anchor"></a><b>§3.6.1.18. Adaptation to EXTREMAL. </b>This is rather similar. We find the member of \(\lbrace x\mid \phi(x)\rbrace\)
|
|
which either minimises, or maximises, the value of some property \(P\). We use
|
|
two local variables: <span class="extract"><span class="extract-syntax">best</span></span>, the extreme \(P\) value found so far; and <span class="extract"><span class="extract-syntax">best_with</span></span>,
|
|
the member of the domain set which achieves that.
|
|
</p>
|
|
|
|
<p class="commentary">If two or more \(x\) achieve the optimal \(P\)-value, it is deliberately left
|
|
undefined which one is returned. The user may be typing "the heaviest thing
|
|
on the table", but what he gets is "a heaviest thing on the table".
|
|
</p>
|
|
|
|
<p class="commentary">We open the search with <span class="extract"><span class="extract-syntax">best_with</span></span> equal to <span class="extract"><span class="extract-syntax">nothing</span></span>, the non-object, which
|
|
is what we will return if the domain set turns out to be empty; and with
|
|
<span class="extract"><span class="extract-syntax">best</span></span> set to the furthest-from-optimal value possible. For a search maximising
|
|
\(P\), <span class="extract"><span class="extract-syntax">best</span></span> starts at the lowest number representable in the virtual machine;
|
|
for a minimisation, it starts at the highest. That way, if any member of the
|
|
domain is found, its \(P\)-value must be at least as good as the starting
|
|
value of <span class="extract"><span class="extract-syntax">best</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">Again the only nuisance is that sometimes we know \(P\), and whether we are
|
|
maximising or minimising, at compile time; but for a multipurpose function
|
|
we don't, and have to look that up at run-time.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before EXTREMAL search</span><span class="named-paragraph-number">3.6.1.18</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFELSE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_LOOP_SIGN_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MIN_NEGATIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MAX_POSITIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">measurement_definition</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mdef</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">RETRIEVE_POINTER_measurement_definition</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MIN_NEGATIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">MAX_POSITIVE_NUMBER_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0],</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_7" class="paragraph-anchor"></a><b>§3.6.1.4.3.7. </b>It might look as if we could speed up the multipurpose case by
|
|
multiplying by <span class="extract"><span class="extract-syntax">property_loop_sign</span></span>, thus combining the max and min
|
|
versions into one, and saving an <span class="extract"><span class="extract-syntax">if</span></span>. But (a) the multiplication is as
|
|
expensive as the <span class="extract"><span class="extract-syntax">if</span></span> (remember that on a VM there's no real branch
|
|
penalty), and (b) we need to watch out because \(-1\) times \(-32768\), on a
|
|
16-bit machine, is \(-1\), not \(32768\): so it is not always true that
|
|
multiplying by \(-1\) is order-reversing.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in EXTREMAL search</span><span class="named-paragraph-number">3.6.1.4.3.7</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFELSE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_LOOP_SIGN_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">LE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">def_prn_sign</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">LE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_7_1" class="named-paragraph-link"><span class="named-paragraph">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_7_1" class="paragraph-anchor"></a><b>§3.6.1.4.3.7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit code for a property lookup</span><span class="named-paragraph-number">3.6.1.4.3.7.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTKindIDs::weak_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multipurpose_function</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PROPERTY_TO_BE_TOTALLED_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">RTProperties::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">def_prn</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3_7">§3.6.1.4.3.7</a> (6 times).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_19" class="paragraph-anchor"></a><b>§3.6.1.19. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after EXTREMAL search</span><span class="named-paragraph-number">3.6.1.19</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_with_s</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_20" class="paragraph-anchor"></a><b>§3.6.1.20. Adaptation to LOOP. </b>Here the proposition is used to iterate through the members of the domain
|
|
set \(\lbrace x\mid \phi(x)\rbrace\). Two local variables exist: <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">x_ix</span></span>.
|
|
One of the following is true:
|
|
</p>
|
|
|
|
<ul class="items"><li>(1) The domain set contains only objects, so that <span class="extract"><span class="extract-syntax">x</span></span> is non-zero if it
|
|
represents a member of that set. In this case <span class="extract"><span class="extract-syntax">x_ix</span></span> may or may not be used,
|
|
and we will not rely on it.
|
|
</li><li>(2) The domain set contains only values, and then <span class="extract"><span class="extract-syntax">x</span></span> might easily be zero,
|
|
but <span class="extract"><span class="extract-syntax">x_ix</span></span> is always the index within the domain set: 1 if <span class="extract"><span class="extract-syntax">x</span></span> is the first
|
|
value, 2 for the second and so on.
|
|
</li></ul>
|
|
<p class="commentary">The proposition is called with a pair of values <span class="extract"><span class="extract-syntax">x</span></span>, <span class="extract"><span class="extract-syntax">x_ix</span></span> and returns
|
|
the next value <span class="extract"><span class="extract-syntax">x</span></span> in the domain set, or 0 if the domain is exhausted. (In
|
|
case (2) it's not safe to regard 0 as an end-of-set sentinel value because
|
|
0 can be a valid member of the set; so in looping through (2) we should
|
|
first find the size of the set using NUMBER OF, then keep calling for
|
|
members until the index reaches the size.) There is no need to return the
|
|
next <span class="extract"><span class="extract-syntax">x_ix</span></span> value since it is always the present value plus 1.
|
|
</p>
|
|
|
|
<p class="commentary">If the proposition is called with <span class="extract"><span class="extract-syntax">x</span></span> set to <span class="extract"><span class="extract-syntax">nothing</span></span>, in case (1), or
|
|
with <span class="extract"><span class="extract-syntax">x_ix</span></span> equal to 0, in case (2), it returns the first value in the
|
|
domain.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_21" class="paragraph-anchor"></a><b>§3.6.1.21. </b>Snarkily, this is how we do it:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> if we're called with a valid member of the domain, go to Z</span>
|
|
<span class="plain-syntax"> loop x over members of the domain {</span>
|
|
<span class="plain-syntax"> return x</span>
|
|
<span class="plain-syntax"> label Z is here</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<p class="commentary">Which is not really a loop at all, but is a cheap way to extract either the
|
|
initial value or the successor value from a loop header.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> This trick caused some consternation for I6 hackers when early drafts of
|
|
I7 came out, because they had been experimenting with a patch to I6 which
|
|
protected <span class="extract"><span class="extract-syntax">objectloop</span></span> from object-tree rearrangements but which assumed that
|
|
nobody ever used <span class="extract"><span class="extract-syntax">jump</span></span> to enter a loop body bypassing its header. But the DM4,
|
|
which defines I6, does not forbid this, and nor does Inter.
|
|
<a href="#fnref:1" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialisation before LOOP search</span><span class="named-paragraph-number">3.6.1.21</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">POSTDECREMENT_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_ix_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::code</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP3_6_1_4_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Jump to next outer loop for this reason</span><span class="named-paragraph-number">3.6.1.4.3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">proposition</span><span class="plain-syntax"> = </span><a href="4-cdp.html#SP5" class="function-link"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></a><span class="plain-syntax">(0, </span><span class="identifier-syntax">var_ix_lv</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">proposition</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_4_3_8" class="paragraph-anchor"></a><b>§3.6.1.4.3.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on successful match in LOOP search</span><span class="named-paragraph-number">3.6.1.4.3.8</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_s</span><span class="plain-syntax">[0]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1_4_3">§3.6.1.4.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_6_1_22" class="paragraph-anchor"></a><b>§3.6.1.22. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Winding-up after LOOP search</span><span class="named-paragraph-number">3.6.1.22</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">RETURN_BIP</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_nothing</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP3_6_1">§3.6.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. Compiling loop headers. </b>The final task of this entire chapter is to compile an Inter loop header which
|
|
causes a given variable \(v\) to range through a domain set \(D\) — which we
|
|
have to deduce by looking at the proposition \(\psi\) in front of us.
|
|
</p>
|
|
|
|
<p class="commentary">We want this loop to run as quickly as possible: efficiency here makes a very
|
|
big difference to the running time of compiled I7 code. Consider compiling
|
|
"everyone in the Dining Room can see an animal". Code like this would run very
|
|
slowly:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> loop over objects (x)</span>
|
|
<span class="plain-syntax"> loop over objects (y)</span>
|
|
<span class="plain-syntax"> if x is a person</span>
|
|
<span class="plain-syntax"> if x is in the Dining Room</span>
|
|
<span class="plain-syntax"> if y is an animal</span>
|
|
<span class="plain-syntax"> if x can see y</span>
|
|
<span class="plain-syntax"> success!</span>
|
|
</pre>
|
|
<p class="commentary">This is folly in so many ways. Most objects are not people or animals, so
|
|
almost all combinations of \(x\) and \(y\) are wasted. We test the eligibility
|
|
of \(x\) for every possible \(y\). And there are quick ways to find what is in
|
|
the Dining Room, so we're missing a trick there, too. What we want is:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> loop over objects in the Dining Room (x)</span>
|
|
<span class="plain-syntax"> if x is a person</span>
|
|
<span class="plain-syntax"> loop over animals (y)</span>
|
|
<span class="plain-syntax"> if x can see y</span>
|
|
<span class="plain-syntax"> success!</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>Part of the work is done already: we generate propositions with
|
|
quantifiers as far forwards as they can be, so we won't loop over \(y\) before
|
|
checking the validity of \(x\). The rest of the work comes from two basic
|
|
optimisations:
|
|
</p>
|
|
|
|
<ul class="items"><li>(1) "Kind optimisation." If a loop over \(v\) is such that \(K(v)\) holds in every case,
|
|
where \(K\) is a kind, then loop \(v\) over \(K\) rather than all objects, and
|
|
</li><li>(2) "Parent optimisation." If a loop over \(v\) is such that \(R(v, t)\) holds in
|
|
every case, then loop over all \(v\) such that \(R(v, t)\) in cases where \(R\) has a
|
|
run-time representation making this quick and easy.
|
|
</li></ul>
|
|
<p class="commentary">In either case we can then delete \(K(v)\) or \(R(v, t)\) from the proposition
|
|
as redundant, since the loop header has taken care of it. "Parent optimisation"
|
|
is so called because the original use of this was to do with the IF world model's
|
|
containment tree, where one object containing another is called its "parent"; but
|
|
in fact it can be applied to any suitable relation \(R\).
|
|
</p>
|
|
|
|
<p class="commentary">Parent optimisation cannot be used if we are compiling code to force a proposition,
|
|
rather than test it, because then \(R(v, t)\) is not an accomplished fact but is
|
|
something we have yet to make come true. This is why the function below needs a
|
|
flag <span class="extract"><span class="extract-syntax">avoid_parent_optimisation</span></span>. Case (1) doesn't suffer from this since
|
|
kinds cannot be changed at run-time.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">i6_schema</span><span class="plain-syntax"> </span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">;</span>
|
|
<span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="function-syntax">DeferredPropositions::compile_loop_header</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">DeferredPropositions::compile_loop_header</span></span>:<br/><a href="4-cdp.html#SP3_6_1_4_2_6">§3.6.1.4.2.6</a>, <a href="4-cdp.html#SP3_6_1_7">§3.6.1.7</a>, <a href="4-cdp.html#SP3_6_1_10">§3.6.1.10</a>, <a href="4-cdp.html#SP3_6_1_12">§3.6.1.12</a>, <a href="4-cdp.html#SP3_6_1_14">§3.6.1.14</a>, <a href="4-cdp.html#SP3_6_1_15">§3.6.1.15</a>, <a href="4-cdp.html#SP3_6_1_18">§3.6.1.18</a>, <a href="4-cdp.html#SP3_6_1_21">§3.6.1.21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">index_var</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proposition</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">avoid_parent_optimisation</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">grouped</span><span class="plain-syntax">, </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">var_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Terms::new_variable</span><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">second_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Terms::new_constant</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Lvalues::new_LOCAL_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">index_var</span><span class="plain-syntax">));</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parent_optimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> the default, if we are unable to provide either kind or parent optimisation</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Calculus::Schemas::modify</span><span class="plain-syntax">(&</span><span class="identifier-syntax">loop_schema</span><span class="plain-syntax">, </span><span class="string-syntax">"objectloop (*1 ofclass Object)"</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-cdp.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Scan the proposition to find the domain of the loop, and look for opportunities</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">parent_optimised</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> parent optimisation is stronger, so we prefer that</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-cl.html#SP3" class="function-link"><span class="function-syntax">CompileLoops::schema</span></a><span class="plain-syntax">(&</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="plain-syntax"> </span><span class="identifier-syntax">Hierarchy::make_iname_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_HL</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterNames::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">-></span><span class="element-syntax">ppd_iname</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Calculus::Schemas::modify</span><span class="plain-syntax">(&</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="4-cs.html#SP1" class="function-link"><span class="function-syntax">CompileSchemas::from_terms_in_void_context</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="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="4-cdp.html#SP5_1_1" class="named-paragraph-link"><span class="named-paragraph">Scan the part of the proposition establishing the domain</span><span class="named-paragraph-number">5.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP5">§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 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="4-cdp.html#SP5_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Consider parent optimisation on this binary predicate</span><span class="named-paragraph-number">5.1.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-cdp.html#SP5_1">§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="4-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 finally concludes the predicate-calculus engine at the heart of Inform.
|
|
</p>
|
|
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="4-cad.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-cv.html">2</a></li><li class="progresschapter"><a href="3-sf.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-cs.html">cs</a></li><li class="progresssection"><a href="4-ca.html">ca</a></li><li class="progresssection"><a href="4-cp.html">cp</a></li><li class="progresssection"><a href="4-cl.html">cl</a></li><li class="progresssection"><a href="4-dtd.html">dtd</a></li><li class="progresssection"><a href="4-cad.html">cad</a></li><li class="progresscurrent">cdp</li><li class="progresschapter"><a href="5-cbal.html">5</a></li><li class="progressnext"><a href="5-cbal.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|