mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
288 lines
45 KiB
HTML
288 lines
45 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Compile 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>
|
||
|
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>
|
||
|
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">
|
||
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
||
|
|
||
|
</head>
|
||
|
<body class="commentary-font">
|
||
|
<nav role="navigation">
|
||
|
<h1><a href="../index.html">
|
||
|
<img src="../docs-assets/Inform.png" height=72">
|
||
|
</a></h1>
|
||
|
<ul><li><a href="../compiler.html">compiler tools</a></li>
|
||
|
<li><a href="../other.html">other tools</a></li>
|
||
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
||
|
<li><a href="../units.html">unit test tools</a></li>
|
||
|
</ul><h2>Compiler Webs</h2><ul>
|
||
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
||
|
<li><a href="../inform7/index.html">inform7</a></li>
|
||
|
<li><a href="../inter/index.html">inter</a></li>
|
||
|
</ul><h2>Inbuild Modules</h2><ul>
|
||
|
<li><a href="../supervisor-module/index.html">supervisor</a></li>
|
||
|
</ul><h2>Inform7 Modules</h2><ul>
|
||
|
<li><a href="../core-module/index.html">core</a></li>
|
||
|
<li><a href="../assertions-module/index.html">assertions</a></li>
|
||
|
<li><a href="../values-module/index.html">values</a></li>
|
||
|
<li><a href="../knowledge-module/index.html">knowledge</a></li>
|
||
|
<li><a href="index.html"><span class="selectedlink">imperative</span></a></li>
|
||
|
<li><a href="../runtime-module/index.html">runtime</a></li>
|
||
|
<li><a href="../if-module/index.html">if</a></li>
|
||
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
||
|
<li><a href="../index-module/index.html">index</a></li>
|
||
|
</ul><h2>Inter Modules</h2><ul>
|
||
|
<li><a href="../bytecode-module/index.html">bytecode</a></li>
|
||
|
<li><a href="../building-module/index.html">building</a></li>
|
||
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
||
|
</ul><h2>Services</h2><ul>
|
||
|
<li><a href="../arch-module/index.html">arch</a></li>
|
||
|
<li><a href="../calculus-module/index.html">calculus</a></li>
|
||
|
<li><a href="../html-module/index.html">html</a></li>
|
||
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
||
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
||
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
||
|
<li><a href="../problems-module/index.html">problems</a></li>
|
||
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
||
|
<li><a href="../words-module/index.html">words</a></li>
|
||
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
||
|
|
||
|
</ul>
|
||
|
</nav>
|
||
|
<main role="main">
|
||
|
<!--Weave of 'Compile Propositions' generated by Inweb-->
|
||
|
<div class="breadcrumbs">
|
||
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7</a></li><li><a href="index.html">imperative</a></li><li><a href="index.html#3">Chapter 3: Propositions</a></li><li><b>Compile Propositions</b></li></ul></div>
|
||
|
<p class="purpose">To compile a proposition within the body of the current function.</p>
|
||
|
|
||
|
<ul class="toc"><li><a href="3-cp.html#SP1">§1. Compiling a test of a proposition</a></li><li><a href="3-cp.html#SP4">§4. Making a proposition true</a></li><li><a href="3-cp.html#SP5">§5. Checking the validity of a description</a></li></ul><hr class="tocbar">
|
||
|
|
||
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Compiling a test of a proposition. </b>Given a proposition \(\phi\), and a value \(v\), we compile a valid condition
|
||
|
to decide whether or not \(\phi(v)\) is true. This is essentially how Inform
|
||
|
compiles something like "if all the doors are closed" — where the proposition
|
||
|
has no free variable, so \(v\) is never substituted — or the test for something
|
||
|
like "taking an open container", where "an open container" is \(\phi\) and \(v\)
|
||
|
is the item being taken.
|
||
|
</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">CompilePropositions::to_test_as_condition</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">CompilePropositions::to_test_as_condition</span></span>:<br/><a href="3-cp.html#SP3">§3</a><br/>Deciding to Defer - <a href="3-dtd.html#SP18">§18</a>, <a href="3-dtd.html#SP21">§21</a><br/>Compile Blocks and Lines - <a href="4-cbal.html#SP4_3_5_1_1">§4.3.5.1.1</a><br/>Compile Invocations - <a href="4-ci.html#SP1_3_1_2_1_1_1">§1.3.1.2.1.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</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_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling as test: $D\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</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">prop</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="comment-syntax"> the empty proposition is always true</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dtd.html#SP6" class="function-link"><span class="function-syntax">Deferrals::defer_test_of_proposition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</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">v</span><span class="plain-syntax">) </span><span class="identifier-syntax">Binding::substitute_var_0_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</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">atom</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">first_atom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prop</span><span class="plain-syntax">, *</span><span class="identifier-syntax">last_atom</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">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">) </span><span class="identifier-syntax">last_atom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">atom</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><a href="3-cp.html#SP2" class="function-link"><span class="function-syntax">CompilePropositions::to_test_segment</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">last_atom</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. </b>The following is used recursively to handle conjunctions and negations: it
|
||
|
tests the portion of a proposition between two atoms (including the two ends).
|
||
|
</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">CompilePropositions::to_test_segment</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">CompilePropositions::to_test_segment</span></span>:<br/><a href="3-cp.html#SP1">§1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from_atom</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">to_atom</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">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</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="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">penultimate_atom</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">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">atom</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">atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</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">atom</span><span class="plain-syntax"> == </span><span class="identifier-syntax">from_atom</span><span class="plain-syntax">) </span><span class="identifier-syntax">active</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">active</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="identifier-syntax">atom</span><span class="plain-syntax"> != </span><span class="identifier-syntax">from_atom</span><span class="plain-syntax">) &&</span>
|
||
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">Propositions::implied_conjunction_between</span><span class="plain-syntax">(</span><span class="identifier-syntax">atom_prev</span><span class="plain-syntax">, </span><span class="identifier-syntax">atom</span><span class="plain-syntax">))) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
||
|
<span class="plain-syntax"> </span><a href="3-cp.html#SP2" class="function-link"><span class="function-syntax">CompilePropositions::to_test_segment</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">atom_prev</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><a href="3-cp.html#SP2" class="function-link"><span class="function-syntax">CompilePropositions::to_test_segment</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_atom</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</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">atom</span><span class="plain-syntax">-></span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEGATION_CLOSE_ATOM</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">atom</span><span class="plain-syntax">-></span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEGATION_OPEN_ATOM</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</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">atom</span><span class="plain-syntax"> == </span><span class="identifier-syntax">to_atom</span><span class="plain-syntax">) { </span><span class="identifier-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="identifier-syntax">penultimate_atom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">atom_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">from_atom</span><span class="plain-syntax">-></span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEGATION_OPEN_ATOM</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">to_atom</span><span class="plain-syntax">-></span><span class="identifier-syntax">element</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEGATION_CLOSE_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">from_atom</span><span class="plain-syntax"> == </span><span class="identifier-syntax">penultimate_atom</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="comment-syntax"> the negation of empty proposition is always false</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">NOT_BIP</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
||
|
<span class="plain-syntax"> </span><a href="3-cp.html#SP2" class="function-link"><span class="function-syntax">CompilePropositions::to_test_segment</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_atom</span><span class="plain-syntax">-></span><span class="identifier-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">penultimate_atom</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">active</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_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</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">atom</span><span class="plain-syntax"> == </span><span class="identifier-syntax">from_atom</span><span class="plain-syntax">) </span><span class="identifier-syntax">active</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">active</span><span class="plain-syntax">) </span><a href="3-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">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">atom</span><span class="plain-syntax"> == </span><span class="identifier-syntax">to_atom</span><span class="plain-syntax">) </span><span class="identifier-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</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 following wrapper tests if a variable \(v\) matches a description \(\phi\), which is a
|
||
|
case we need often enough to be worth its own function.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">If the variable has kind \(K\) then we conjoin to form \({\it kind}_K(v)\land\phi(v)\).
|
||
|
This will cause typechecking to fail if, say, the description "an open door" is
|
||
|
tested on a variable of kind "number". But we issue no problem message in that
|
||
|
case: we simply compile the condition as falsity. In this way, the test correctly
|
||
|
fails and without performing any type-unsafe operations on the value of the variable.
|
||
|
</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">CompilePropositions::to_test_if_variable_matches</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">CompilePropositions::to_test_if_variable_matches</span></span>:<br/>Compile Invocations - <a href="4-ci.html#SP1_3_1_2_1_1_1">§1.3.1.2.1.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">desc</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">desc</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"VMD against null description"</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">v</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"VMD on null variable"</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">Lvalues::get_storage_form</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">) != </span><span class="identifier-syntax">NONLOCAL_VARIABLE_NT</span><span class="plain-syntax">) &&</span>
|
||
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">Lvalues::get_storage_form</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">) != </span><span class="identifier-syntax">LOCAL_VARIABLE_NT</span><span class="plain-syntax">))</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"VMD on non-variable"</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</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">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SentencePropositions::from_spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">desc</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">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::concatenate</span><span class="plain-syntax">(</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">KindPredicates::new_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">Terms::new_variable</span><span class="plain-syntax">(0)), </span><span class="identifier-syntax">prop</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">DESCRIPTION_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"[VMD: $P (%u) matches $D]\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</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">TypecheckPropositions::type_check</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">,</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TypecheckPropositions::tc_no_problem_reporting</span><span class="plain-syntax">()) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</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><a href="3-cp.html#SP1" class="function-link"><span class="function-syntax">CompilePropositions::to_test_as_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. Making a proposition true. </b>Given a proposition \(\phi\) with no free variables, compile code to make the
|
||
|
state of affairs it describes true. This is essentially how Inform compiles
|
||
|
something like "now all the doors are closed".
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">This is simpler, but a question arises of how to force \(\lnot(\phi\land\psi)\) to
|
||
|
be true. It would be sufficient to falsify either one of \(\phi\) or \(\psi\)
|
||
|
alone, but for the sake of symmetry we falsify both. (We took the same
|
||
|
decision when asserting propositions about the initial state of the model.)
|
||
|
</p>
|
||
|
|
||
|
<pre class="displayed-code all-displayed-code code-font">
|
||
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CompilePropositions::to_make_true</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">CompilePropositions::to_make_true</span></span>:<br/>Deciding to Defer - <a href="3-dtd.html#SP19">§19</a><br/>Compile Blocks and Lines - <a href="4-cbal.html#SP4_3_2">§4.3.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</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_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling as 'now': $D\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dtd.html#SP8" class="function-link"><span class="function-syntax">Deferrals::defer_now_proposition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prop</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">int</span><span class="plain-syntax"> </span><span class="identifier-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">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">atom</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">atom</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</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">atom</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="identifier-syntax">parity</span><span class="plain-syntax"> = (</span><span class="identifier-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="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><a href="3-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">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">atom</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>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Checking the validity of a description. </b>The following utility routine checks that a proposition contains exactly one
|
||
|
free variable, producing problem messages if not — all of that is really just
|
||
|
defensive programming; if Inform is correctly written, none of these conditions
|
||
|
can ever occur — but also typechecking the proposition, which does do something
|
||
|
and can indeed throw problems.
|
||
|
</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">CompilePropositions::verify_descriptive</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">CompilePropositions::verify_descriptive</span></span>:<br/>Deciding to Defer - <a href="3-dtd.html#SP12">§12</a>, <a href="3-dtd.html#SP14">§14</a>, <a href="3-dtd.html#SP15">§15</a>, <a href="3-dtd.html#SP17">§17</a>, <a href="3-dtd.html#SP20">§20</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">billing</span><span class="plain-syntax">,</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">constructor</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">constructor</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"description with null constructor"</span><span class="plain-syntax">);</span>
|
||
|
|
||
|
<span class="plain-syntax"> </span><span class="comment-syntax"> best guess at the text to quote in any problem message</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">EW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">constructor</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">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">EW</span><span class="plain-syntax">)) && (</span><span class="identifier-syntax">constructor</span><span class="plain-syntax">-></span><span class="identifier-syntax">down</span><span class="plain-syntax">))</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">constructor</span><span class="plain-syntax">-></span><span class="identifier-syntax">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">Binding::is_well_formed</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"malformed proposition in description verification"</span><span class="plain-syntax">);</span>
|
||
|
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Binding::number_free</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</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">N</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">TypecheckPropositions::type_check</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">,</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TypecheckPropositions::tc_problem_reporting</span><span class="plain-syntax">(</span><span class="identifier-syntax">EW</span><span class="plain-syntax">,</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"involve a range of objects matching a description"</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">N</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">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">billing</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">EW</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_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="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you are asking for %2, but this should range over a simpler "</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"description than '%3', please - it should not include any determiners such "</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"as 'at least three', 'all' or 'most'. (The range is always taken to be all "</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"of the things matching the description.)"</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</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">N</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">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">billing</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">EW</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_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="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you are asking for %2, but '%3' looks as if it ranges over only a "</span>
|
||
|
<span class="plain-syntax"> </span><span class="string-syntax">"single specific object, not a whole collection of objects."</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<nav role="progress"><div class="progresscontainer">
|
||
|
<ul class="progressbar"><li class="progressprev"><a href="3-ca.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-sf.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresssection"><a href="3-cv.html">cv</a></li><li class="progresssection"><a href="3-cs.html">cs</a></li><li class="progresssection"><a href="3-ca.html">ca</a></li><li class="progresscurrent">cp</li><li class="progresssection"><a href="3-dtd.html">dtd</a></li><li class="progresssection"><a href="3-cad.html">cad</a></li><li class="progresssection"><a href="3-cdp.html">cdp</a></li><li class="progresschapter"><a href="4-cbal.html">4</a></li><li class="progressnext"><a href="3-dtd.html">❯</a></li></ul></div>
|
||
|
</nav><!--End of weave-->
|
||
|
|
||
|
</main>
|
||
|
</body>
|
||
|
</html>
|
||
|
|