1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/core-module/12-ap.html
2020-04-07 01:06:09 +01:00

1117 lines
119 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>12/qr</title>
<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="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></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="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</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="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '12/ap' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#12">Chapter 12: Use of Propositions</a></li><li><b>Assert Propositions</b></li></ul><p class="purpose">To declare that a given proposition is a true statement about the state of the world when play begins.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP5">&#167;5. Entrance</a></li><li><a href="#SP9">&#167;9. Main procedure</a></li><li><a href="#SP9_5">&#167;9.5. Creations</a></li><li><a href="#SP9_6">&#167;9.6. Asserting kinds</a></li><li><a href="#SP9_7">&#167;9.7. Asserting HERE, NOWHERE and EVERYWHERE</a></li><li><a href="#SP9_10">&#167;9.10. Asserting predicates</a></li><li><a href="#SP11">&#167;11. Evaluating terms</a></li><li><a href="#SP13">&#167;13. Testing at compile-time</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Inside Inform, the term "the model" means the collection of the following:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(1) The inference subjects capable of holding properties, divided into:
<ul class="items"><li>(1a) World objects, such as "Brazilian frog" or "Jungle Clearing"; each
of which belongs to a kind;
</li><li>(1b) Kinds of object, such as "animal" or "room"; each of which
is a kind in turn of another kind, even if only "kind", which is its own kind;
</li><li>(1c) Named constant values, such as "red" or "Entire Game"; each of which
belongs to a kind of value;
</li><li>(1d) Kinds of value whose values are all named, such as "colour" or "scene".
</li></ul>
</li></ul>
<p class="inwebparagraph"></p>
<ul class="items"><li>(2) The associated values, divided into:
<ul class="items"><li>(2a) Properties, such as "open" or "carrying capacity", each of which is
held by some subset of the objects &mdash; for instance, containers and people are
permitted to have the "carrying capacity" property;
</li><li>(2b) Global variables, such as "time of day".
</li></ul>
</li></ul>
<p class="inwebparagraph"></p>
<ul class="items"><li>(3) Relations between the objects (or in some cases between objects and values
outside the model), such as "containment".
</li></ul>
<p class="inwebparagraph">Much else lies outside the model: values like <code class="display"><span class="extract">152</span></code> or <code class="display"><span class="extract">"alfalfa"</span></code>, rules,
rulebooks, phrases, relations which can only be tested (such as "less than"
or "visibility") and so on. Some of this is excluded because it is beyond
the source text's power to decide facts about it (for instance, that 5 is
less than 6); other matter is left out because it only relates to what
happens to the world after its initial creation (for instances, actions
and activities). The model is that which the source text can decide about
the initial state of things.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The initial state of the world is built from the model. Properly speaking
a few other things contribute, too &mdash; such as the entries initially found in
table cells &mdash; but these don't need careful handling, since they are explicitly
declared as literals in the source text: there is no need to analyse their
meaning.
</p>
<p class="inwebparagraph">To build or change the model, we assert that propositions about it are true,
using <code class="display"><span class="extract">Calculus::Propositions::Assert::assert_true</span></code> or
<code class="display"><span class="extract">Calculus::Propositions::Assert::assert_true_about</span></code>. This is the only way to
create kinds, instances, global variables, and constant values, and also the
only way to attach properties to objects, to set property values or
the kind of a given object or the value of a global variable, or to declare
that relationships hold.
</p>
<p class="inwebparagraph">However, creating new property names and new relations does not count as a
change in the model world. (After all, we could create a new property
called "scent" and a new relation called "admiring", but then choose
not to attach scent to anything or to relate any objects by admiring. The
model world would then not have changed at all.) So creating new properties
and new relations is not done by asserting propositions.
</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b><code class="display"><span class="extract">Calculus::Propositions::Assert::assert_true</span></code> asserts propositions in which all variables are
bound (or which have no variables); <code class="display"><span class="extract">Calculus::Propositions::Assert::assert_true_about</span></code> asserts
propositions in which x is free but all other variables are bound, and
substitutes either an object O or a value V into x before asserting.
These two procedures are the entire API, so to speak, for growing or changing
the model. They are used by the detailed-look part of the A-parser,
which takes assertion sentences in the source text and
converts them into a series of propositions which it would like to make true.
</p>
<p class="inwebparagraph">Either way those requests come in, they all end up in the central
<code class="display"><span class="extract">Calculus::Propositions::Assert::prop_true_in_model</span></code> procedure, one of the most important choke points within
Inform. <code class="display"><span class="extract">Calculus::Propositions::Assert::prop_true_in_model</span></code> and its delegates &mdash; routines to assert the
truth of various adjectives or relations &mdash; are allowed to call routines such
as <code class="display"><span class="extract">Instances::set_kind</span></code> and <code class="display"><span class="extract">Instances::new</span></code> which are forbidden for use in the
rest of Inform. These are guarded with the following macro, to ensure that
we don't accidentally break this rule:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PROTECTED_MODEL_PROCEDURE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ptim_recursion_depth</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"protected model-affecting procedure used outside proposition assert"</span><span class="plain">);</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ptim_recursion_depth</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="comment">depth of recursion of <code class="display"><span class="extract">Calculus::Propositions::Assert::prop_true_in_model</span></code></span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Entrance. </b>This first entrance is a mere alias for the second.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::assert_true</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">certitude</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Propositions::Assert::prop_true_in_world_model_inner</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">certitude</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">certitude</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Propositions::Assert::prop_true_in_world_model_inner</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">certitude</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::assert_true is used in 3/nl (<a href="3-nl.html#SP4">&#167;4</a>), 9/tc (<a href="9-tc.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="9-tc.html#SP5_4_2_1">&#167;5.4.2.1</a>, <a href="9-tc.html#SP5_4_2_2">&#167;5.4.2.2</a>, <a href="9-tc.html#SP5_4_2_3">&#167;5.4.2.3</a>, <a href="9-tc.html#SP8_4_1">&#167;8.4.1</a>), 9/pk (<a href="9-pk.html#SP2">&#167;2</a>), 9/rk (<a href="9-rk.html#SP3">&#167;3</a>), 9/pd (<a href="9-pd.html#SP5_11">&#167;5.11</a>), 15/cp (<a href="15-cp.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Calculus::Propositions::Assert::assert_true_about is used in 6/rlt (<a href="6-rlt.html#SP9">&#167;9</a>), 9/ma (<a href="9-ma.html#SP3_3_39_5">&#167;3.3.39.5</a>), 9/pk (<a href="9-pk.html#SP3">&#167;3</a>), 9/rk (<a href="9-rk.html#SP1_2">&#167;1.2</a>), 9/imp (<a href="9-imp.html#SP7_1_3">&#167;7.1.3</a>), 9/pd (<a href="9-pd.html#SP5_9">&#167;5.9</a>, <a href="9-pd.html#SP5_10">&#167;5.10</a>, <a href="9-pd.html#SP6_1">&#167;6.1</a>), 11/tc (<a href="11-tc.html#SP2">&#167;2</a>), 15/ep (<a href="15-ep.html#SP9">&#167;9</a>), 15/vp (<a href="15-vp.html#SP10">&#167;10</a>), 19/tod (<a href="19-tod.html#SP6_4">&#167;6.4</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>If we are working along a proposition and reach, say, door(x), we
can only assert that if we know what the value of x is. We therefore keep
an array (or a pair of arrays) holding our current beliefs about the values
of the variables &mdash; this is called the "identification slate".
</p>
<pre class="display">
<span class="reserved">inference_subject</span><span class="plain"> **</span><span class="identifier">current_interpretation_as_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">must point to a 26-element array</span>
<span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">current_interpretation_as_spec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">must point to a 26-element array</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Purely to avoid multiply producing a problem message.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">last_couldnt_assert_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>The second entrance, then, keeps track of the recursion depth but also
ensures that the identification slate is always correct, stacking them
so that an inner <code class="display"><span class="extract">Calculus::Propositions::Assert::prop_true_in_model</span></code> has an independent slate from an outer
one.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::prop_true_in_world_model_inner</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subject</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">certainty</span><span class="plain">) {</span>
<span class="reserved">inference_subject</span><span class="plain"> **</span><span class="identifier">saved_interpretation_as_infs</span><span class="plain"> = </span><span class="identifier">current_interpretation_as_infs</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">saved_interpretation_as_spec</span><span class="plain"> = </span><span class="identifier">current_interpretation_as_spec</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">saved_prevailing_mood</span><span class="plain"> = </span><span class="identifier">prevailing_mood</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">certainty</span><span class="plain"> != </span><span class="identifier">UNKNOWN_CE</span><span class="plain">) </span><span class="identifier">prevailing_mood</span><span class="plain"> = </span><span class="identifier">certainty</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">ciawo</span><span class="plain">[26]; </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">ciats</span><span class="plain">[26];</span>
&lt;<span class="cwebmacro">Establish a new identification slate for the variables in the proposition</span> <span class="cwebmacronumber">8.1</span>&gt;<span class="plain">;</span>
<span class="identifier">ptim_recursion_depth</span><span class="plain">++;</span>
<span class="functiontext">Calculus::Propositions::Assert::prop_true_in_model</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">ptim_recursion_depth</span><span class="plain">--;</span>
<span class="identifier">prevailing_mood</span><span class="plain"> = </span><span class="identifier">saved_prevailing_mood</span><span class="plain">;</span>
<span class="identifier">current_interpretation_as_infs</span><span class="plain"> = </span><span class="identifier">saved_interpretation_as_infs</span><span class="plain">;</span>
<span class="identifier">current_interpretation_as_spec</span><span class="plain"> = </span><span class="identifier">saved_interpretation_as_spec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::prop_true_in_world_model_inner is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP8_1"></a><b>&#167;8.1. </b>The slate is initially blank unless substitutions for variable x have
been supplied; x of course is variable number 0.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Establish a new identification slate for the variables in the proposition</span> <span class="cwebmacronumber">8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;26; </span><span class="identifier">k</span><span class="plain">++) { </span><span class="identifier">ciawo</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">ciats</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">; }</span>
<span class="identifier">ciawo</span><span class="plain">[0] = </span><span class="identifier">subject</span><span class="plain">; </span><span class="identifier">ciats</span><span class="plain">[0] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">current_interpretation_as_infs</span><span class="plain"> = </span><span class="identifier">ciawo</span><span class="plain">; </span><span class="identifier">current_interpretation_as_spec</span><span class="plain"> = </span><span class="identifier">ciats</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Main procedure. </b>As can be seen, <code class="display"><span class="extract">Calculus::Propositions::Assert::prop_true_in_model</span></code> is a simple procedure. After a little
fuss to check that everything is set up right, we simply run through the
proposition one atom at a time.
</p>
<p class="inwebparagraph">This is a modest scheme. We are unable to assert any proposition other
than ∃, so that we never see their attendant domain brackets.
We are therefore left with a proposition in the form P_1∧ P_2∧ ...
∧ P_n where each P_i is either a predicate-like atom, an ∃ v
term for some variable v, or else ¬(...) of a similar conjunction.
</p>
<p class="inwebparagraph">This is an ambiguous task if we have to assert ¬(P∧ Q), which is
in effect a form of disjunction: P∧ Q fails if either is false, so
which do we falsify? We choose both.
</p>
<p class="inwebparagraph">That means we can simply assert each atom in turn, with a parity depending on
its nesting in negation brackets, which is nice and easy to write:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::prop_true_in_model</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prop</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Record the proposition in the debugging log</span> <span class="cwebmacronumber">9.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::contains_nonexistence_quantifier</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem message explaining that the proposition isn't exact enough</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Typecheck the proposition, in case this has not already been done</span> <span class="cwebmacronumber">9.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check the identification slate against variable usage in the proposition</span> <span class="cwebmacronumber">9.4</span>&gt;<span class="plain">;</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">now_negated</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NEGATION_OPEN_ATOM:</span><span class="plain"> </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">NEGATION_CLOSE_ATOM:</span>
<span class="identifier">now_negated</span><span class="plain"> = (</span><span class="identifier">now_negated</span><span class="plain">)?</span><span class="identifier">FALSE:TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">QUANTIFIER_ATOM:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Assert the truth or falsity of a QUANTIFIER atom</span> <span class="cwebmacronumber">9.5</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">KIND_ATOM:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Assert the truth or falsity of a KIND atom</span> <span class="cwebmacronumber">9.6</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PREDICATE_ATOM:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">: </span>&lt;<span class="cwebmacro">Assert the truth or falsity of a unary predicate</span> <span class="cwebmacronumber">9.10</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">2</span><span class="plain">: </span>&lt;<span class="cwebmacro">Assert the truth or falsity of a binary predicate</span> <span class="cwebmacronumber">9.11</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">HERE_ATOM:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Assert the truth or falsity of a HERE atom</span> <span class="cwebmacronumber">9.9</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">EVERYWHERE_ATOM:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Assert the truth or falsity of an EVERYWHERE atom</span> <span class="cwebmacronumber">9.7</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NOWHERE_ATOM:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Assert the truth or falsity of a NOWHERE atom</span> <span class="cwebmacronumber">9.8</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ISAKIND_ATOM:</span><span class="plain"> </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">ISAVAR_ATOM:</span><span class="plain"> </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">ISACONST_ATOM:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"ISA... atoms cannot be negated"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::prop_true_in_model is used in <a href="#SP4">&#167;4</a>, <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>The certainty, the initial interpretation slate, and the proposition are
combined into a single line in the log:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Record the proposition in the debugging log</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">"::"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">prevailing_mood</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">IMPOSSIBLE_CE:</span><span class="plain"> </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" (impossible)"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">UNLIKELY_CE:</span><span class="plain"> </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" (unlikely)"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">UNKNOWN_CE:</span><span class="plain"> </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" (no certainty)"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIKELY_CE:</span><span class="plain"> </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" (likely)"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">INITIALLY_CE:</span><span class="plain"> </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" (initially)"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">CERTAIN_CE:</span><span class="plain"> </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">" (unknown certainty)"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;26; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" %c = $j"</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" %c = $P"</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">" $D\n"</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b>It's surprisingly hard to get this problem message, because the assertion-maker
rejects most of the obvious ways to try it with more direct problems. It took
me about twenty sentences to get there ("The car is a vehicle in most rooms
which are dark" will do it).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message explaining that the proposition isn't exact enough</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantAssertQuantifier</span><span class="plain">),</span>
<span class="string">"the relationship you describe is not exact enough"</span><span class="plain">,</span>
<span class="string">"so that I cannot be sure of the initial situation. A specific "</span>
<span class="string">"relationship would be something like 'the box is a container in "</span>
<span class="string">"the Attic', rather than 'the box is a container in a room which "</span>
<span class="string">"is dark' (fine, but which dark room? You must say)."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b>Almost all propositions derive from sentences in the source text, but a
crucial exception is the first one to be asserted: ∃ x: isakind(x),
which creates the kind "kind". Type-checking problems never arise with this
in any case, so it doesn't matter that we wouldn't know what text to use in them.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Typecheck the proposition, in case this has not already been done</span> <span class="cwebmacronumber">9.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_sentence</span><span class="plain">) </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::Checker::type_check</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">,</span>
<span class="functiontext">Calculus::Propositions::Checker::tc_problem_reporting</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="string">"be asserting something"</span><span class="plain">))</span>
<span class="plain">!= </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_4"></a><b>&#167;9.4. </b>This does nothing functional, except that it allows an interpretation as an
instance to trump one as a specification; useful since the A-parser
often specifies O and V as the object and value referred to by a given
node in the parse tree, and since an object is also a value, this often means
that both are given. If we have O, then, we cancel V.
</p>
<p class="inwebparagraph">As we shall see, it's permitted to interpret a bound variable after its
quantifier, but not before, and in particular not at the start of the
proposition. So we require that the slate identify exactly the free
variables, and no others.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check the identification slate against variable usage in the proposition</span> <span class="cwebmacronumber">9.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">valid</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">[26];</span>
<span class="functiontext">Calculus::Variables::determine_status</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">var_states</span><span class="plain">, &amp;</span><span class="identifier">valid</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">valid</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to assert malformed proposition"</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;26; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">set</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) </span><span class="identifier">set</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) </span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">set</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="constant">UNUSED_VST</span><span class="plain">) &amp;&amp; (</span><span class="identifier">set</span><span class="plain">))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set an unused variable"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="constant">BOUND_VST</span><span class="plain">) &amp;&amp; (</span><span class="identifier">set</span><span class="plain">))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set a bound variable"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">var_states</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="constant">FREE_VST</span><span class="plain">) &amp;&amp; (</span><span class="identifier">set</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"failed to set a free variable"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_5"></a><b>&#167;9.5. Creations. </b>To assert the truth of ∃ x, we must create an object to become x;
that will provide a value in subsequent uses of x in the same proposition,
so the new value has to be added to the identification slate.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of a QUANTIFIER atom</span> <span class="cwebmacronumber">9.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0].</span><span class="element">variable</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">v</span><span class="plain"> == -1) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad QUANTIFIER atom"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to negate existence"</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">is_a_var</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">is_a_const</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">is_a_kind</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Scan subsequent atoms to find the name, nature and kind of what is to be created</span> <span class="cwebmacronumber">9.5.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Create the object and add to the identification slate</span> <span class="cwebmacronumber">9.5.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Record the new creation in the debugging log</span> <span class="cwebmacronumber">9.5.3</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_5_1"></a><b>&#167;9.5.1. </b>Note that all four of these atoms are optional; the proposition might consist
of just ∃ x alone, which creates a nameless object, since as usual we
interpret no indication of a kind as meaning "object".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Scan subsequent atoms to find the name, nature and kind of what is to be created</span> <span class="cwebmacronumber">9.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">lookahead</span><span class="plain">);</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">lookahead</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lookahead</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">lookahead</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0].</span><span class="element">variable</span><span class="plain"> == </span><span class="identifier">v</span><span class="plain">)) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">lookahead</span><span class="plain">-&gt;</span><span class="element">element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">KIND_ATOM:</span><span class="plain"> </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">lookahead</span><span class="plain">-&gt;</span><span class="element">assert_kind</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">CALLED_ATOM:</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::CALLED_get_name</span><span class="plain">(</span><span class="identifier">lookahead</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ISAKIND_ATOM:</span><span class="plain"> </span><span class="identifier">is_a_kind</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">lookahead</span><span class="plain">-&gt;</span><span class="element">assert_kind</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ISAVAR_ATOM:</span><span class="plain"> </span><span class="identifier">is_a_var</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ISACONST_ATOM:</span><span class="plain"> </span><span class="identifier">is_a_const</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_5">&#167;9.5</a>.</p>
<p class="inwebparagraph"><a id="SP9_5_2"></a><b>&#167;9.5.2. </b>There are really three cases: new kind, new global variable, new instance.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Create the object and add to the identification slate</span> <span class="cwebmacronumber">9.5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">is_a_kind</span><span class="plain">) {</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">Kinds::new_base</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">is_a_var</span><span class="plain">) || (</span><span class="identifier">is_a_const</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::new_global</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="functiontext">Lvalues::new_actual_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">is_a_const</span><span class="plain">) </span><span class="functiontext">NonlocalVariables::make_constant</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">nc</span><span class="plain"> = </span><span class="functiontext">Instances::new</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)))</span>
<span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">] = </span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_5">&#167;9.5</a>.</p>
<p class="inwebparagraph"><a id="SP9_5_3"></a><b>&#167;9.5.3. </b>It's useful to log the new creation, especially for objects which have
duplicate names to others already made:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Record the new creation in the debugging log</span> <span class="cwebmacronumber">9.5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">]) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">":: %c &lt;-- $P\n"</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">], </span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">]) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSERTIONS</span><span class="plain">, </span><span class="string">":: %c &lt;-- $j\n"</span><span class="plain">, </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">], </span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">]);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_5">&#167;9.5</a>.</p>
<p class="inwebparagraph"><a id="SP9_6"></a><b>&#167;9.6. Asserting kinds. </b>Note that we never assert the kind of non-objects. Typechecking won't allow such
an atom to exist unless it states something already true, so there is no need.
</p>
<p class="inwebparagraph">Once again, the problem messages in this section for negated attempts are
really quite hard to generate, because the A-parser usually gets there first.
"There is a banana which is something which is not a door." will fall
through here, but it isn't exactly an everyday sentence.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of a KIND atom</span> <span class="cwebmacronumber">9.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantAssertNonKind</span><span class="plain">),</span>
<span class="string">"that seems to say what kind something doesn't have"</span><span class="plain">,</span>
<span class="string">"which is too vague. You must say what kind it does have."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0]);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">ox</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">subj</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain">) </span><span class="functiontext">Instances::set_kind</span><span class="plain">(</span><span class="identifier">ox</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">assert_kind</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_kind</span><span class="plain">(</span><span class="identifier">subj</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="identifier">Kinds::Compare::make_subkind</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">assert_kind</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_7"></a><b>&#167;9.7. Asserting HERE, NOWHERE and EVERYWHERE. </b>Three special cases. The first, EVERYWHERE, declares that something is found
in every room. While we could simply deduce that the object must be a
backdrop (and set the kind to make it so), this is such an extreme business,
so rarely needed, that it seems better to make the user spell out that
we're dealing with a backdrop. So we play dumb.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of an EVERYWHERE atom</span> <span class="cwebmacronumber">9.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantAssertNegatedEverywhere</span><span class="plain">),</span>
<span class="string">"that seems to say that something isn't everywhere"</span><span class="plain">,</span>
<span class="string">"which is too vague. You must say where it is."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0]);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">ox</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">subj</span><span class="plain">);</span>
<span class="identifier">PL::Backdrops::infer_presence_everywhere</span><span class="plain">(</span><span class="identifier">ox</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_8"></a><b>&#167;9.8. </b>NOWHERE is similar:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of a NOWHERE atom</span> <span class="cwebmacronumber">9.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0]);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">ox</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">subj</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
<span class="string">"that seems to say that something isn't nowhere"</span><span class="plain">,</span>
<span class="string">"which is too vague. You must say where it is."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
<span class="string">"that seems to say that something generic is 'nowhere'"</span><span class="plain">,</span>
<span class="string">"which suggests it could some day have a physical location."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">PL::Spatial::infer_presence_nowhere</span><span class="plain">(</span><span class="identifier">ox</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_9"></a><b>&#167;9.9. </b>HERE means "this object is in the current room", which is not as easy to
resolve as it looks, because at this point we don't know for certain what
will be a room and what won't. So we record a special inference and put the
problem aside for now.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of a HERE atom</span> <span class="cwebmacronumber">9.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0]);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">ox</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">subj</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
<span class="string">"that seems to say that something isn't here"</span><span class="plain">,</span>
<span class="string">"which is too vague. You must say where it is."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NonInstanceHere</span><span class="plain">),</span>
<span class="string">"that seems to say that something generic is 'here'"</span><span class="plain">,</span>
<span class="string">"which would give it a physical location. (It would be like saying "</span>
<span class="string">"'A number is here' - well, numbers are everywhere and nowhere.)"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">PL::Spatial::infer_presence_here</span><span class="plain">(</span><span class="identifier">ox</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_10"></a><b>&#167;9.10. Asserting predicates. </b>First, asserting adjective(t). We know that t evaluates to a kind
of value over which adjective is defined, or the proposition would
not have survived type-checking. But only some adjectives can be asserted;
"open" can, but "visible" can't, for instance. <code class="display"><span class="extract">Adjectives::Meanings::assert</span></code> returns a
success flag.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of a unary predicate</span> <span class="cwebmacronumber">9.10</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">tr</span><span class="plain"> = </span><span class="identifier">RETRIEVE_POINTER_adjective_usage</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">predicate</span><span class="plain">);</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::get_aph</span><span class="plain">(</span><span class="identifier">tr</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">parity</span><span class="plain"> = (</span><span class="identifier">now_negated</span><span class="plain">)?</span><span class="identifier">FALSE:TRUE</span><span class="plain">, </span><span class="identifier">found</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">AdjectiveUsages::get_parity</span><span class="plain">(</span><span class="identifier">tr</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">parity</span><span class="plain"> = (</span><span class="identifier">parity</span><span class="plain">)?</span><span class="identifier">FALSE:TRUE</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">ox</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0]);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">ots</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::spec_of_term</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[0]);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">domain_of_definition</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">ox</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain_of_definition</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">inst</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">ox</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inst</span><span class="plain">) </span><span class="identifier">domain_of_definition</span><span class="plain"> = </span><span class="functiontext">Instances::to_kind</span><span class="plain">(</span><span class="identifier">inst</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">try</span><span class="plain"> = </span><span class="identifier">ox</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">domain_of_definition</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">try</span><span class="plain">)) {</span>
<span class="identifier">domain_of_definition</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">try</span><span class="plain">);</span>
<span class="identifier">try</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">try</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain_of_definition</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">domain_of_definition</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">ots</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain">) </span><span class="identifier">found</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::assert</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">domain_of_definition</span><span class="plain">, </span><span class="identifier">ox</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">parity</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">found</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::assert</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">domain_of_definition</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">ots</span><span class="plain">, </span><span class="identifier">parity</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_couldnt_assert_at</span><span class="plain"> != </span><span class="identifier">current_sentence</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Adjectives::get_text</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantAssertAdjective</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parity</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the sentence %1, you ask me to arrange for something not to be "</span>
<span class="string">"'%2' at the start of play. This is only possible when an adjective "</span>
<span class="string">"talks about an either/or property, like 'open'/'closed' - if there "</span>
<span class="string">"are three or more possibilities then it's ambiguous. Even if there "</span>
<span class="string">"are only two possibilities, I can't always fix them just on your "</span>
<span class="string">"request - 'visible'/'invisible', for instance, is something I can "</span>
<span class="string">"test during play at any time, but not something I can arrange at "</span>
<span class="string">"the start."</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the sentence %1, you ask me to arrange for something to be '%2' "</span>
<span class="string">"at the start of play. There are some adjectives ('open' or 'dark', "</span>
<span class="string">"for instance) which I can fix, but others are just too vague. For "</span>
<span class="string">"example, saying 'Peter is visible.' isn't allowed, because it "</span>
<span class="string">"doesn't tell me where Peter is. Like 'visible', being '%2' is "</span>
<span class="string">"something I can test during play at any time, but not something "</span>
<span class="string">"I can arrange at the start."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">last_couldnt_assert_at</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_11"></a><b>&#167;9.11. </b>Binary predicates, unlike unary ones, can only be asserted positively. This
is because ¬ P(x) tells you something fairly definite, whereas ¬ Q(x, y)
gives no information about what z might exist, if any, such that Q(x, z).
For instance, knowing that X is not part of Y gives us no help in determining
where X is.
</p>
<p class="inwebparagraph">Another difference is that R(x, y) can give you definite information about
the kinds of x and y, where they are objects, because binary predicates
have single definitions. (Knowing locked(x), by contrast, doesn't
tell you whether x is a door or a container &mdash; adjectives can have multiple
domains in which they have differing definitions.) In the case of a
proposition produced by sentence conversion, that information is redundant
since appropriate kind atoms were added to the proposition anyway. But we
also assert propositions generated from tree conversion, which don't have
these kind atoms.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assert the truth or falsity of a binary predicate</span> <span class="cwebmacronumber">9.11</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">now_negated</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantAssertNegatedRelations</span><span class="plain">),</span>
<span class="string">"that seems to make a negative statement about a relationship"</span><span class="plain">,</span>
<span class="string">"which is too vague. You must make positive assertions."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">;</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt0</span><span class="plain">, </span><span class="identifier">pt1</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Determine the BP and terms to be asserted</span> <span class="cwebmacronumber">9.11.2</span>&gt;<span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec0</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::spec_of_term</span><span class="plain">(</span><span class="identifier">pt0</span><span class="plain">), *</span><span class="identifier">spec1</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::spec_of_term</span><span class="plain">(</span><span class="identifier">pt1</span><span class="plain">);</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj0</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pt0</span><span class="plain">), *</span><span class="identifier">subj1</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="identifier">pt1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">subj0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">spec0</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">spec0</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_constant</span><span class="plain">(</span><span class="identifier">subj0</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">subj1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">spec1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">spec1</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_constant</span><span class="plain">(</span><span class="identifier">subj1</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> != </span><span class="identifier">R_regional_containment</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K0</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K1</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">K0</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="functiontext">Calculus::Propositions::Assert::cautiously_set_kind</span><span class="plain">(</span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">K0</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="functiontext">Calculus::Propositions::Assert::cautiously_set_kind</span><span class="plain">(</span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">K1</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">BinaryPredicates::assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem message for failure to assert</span> <span class="cwebmacronumber">9.11.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_11_1"></a><b>&#167;9.11.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for failure to assert</span> <span class="cwebmacronumber">9.11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$2 on ($j, $P; $j, $P)\n"</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Rvalues::is_nothing_object_constant</span><span class="plain">(</span><span class="identifier">spec0</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">Rvalues::is_nothing_object_constant</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">)))</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelationFailedOnNothing</span><span class="plain">),</span>
<span class="string">"that is an assertion which involves 'nothing'"</span><span class="plain">,</span>
<span class="string">"which looks as if it might be trying to give me negative rather "</span>
<span class="string">"than positive information. There's no need to tell me something "</span>
<span class="string">"like 'Nothing is in the box.': just don't put anything in the box, "</span>
<span class="string">"and then nothing will be in it."</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
<span class="string">"that is an assertion I can't puzzle out"</span><span class="plain">,</span>
<span class="string">"which seems to involve placing two things in some sort of "</span>
<span class="string">"relationship, but if so then I can't make it work. Perhaps the "</span>
<span class="string">"sentence is too complicatedly phrased, and could be broken up "</span>
<span class="string">"into two or more sentences?"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_11">&#167;9.11</a>.</p>
<p class="inwebparagraph"><a id="SP9_11_2"></a><b>&#167;9.11.2. </b>The "is" predicate is not usually assertable, but is(x, f_R(y))
can be asserted since it is equivalent to R(x, y) &mdash; this is where we
unravel that. We reject compound uses of functions in this way, but in
practice they hardly ever arise, and could only do so with quite complex
sentences where it seems reasonable to tell the user to write something
simpler and clearer.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Determine the BP and terms to be asserted</span> <span class="cwebmacronumber">9.11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">RETRIEVE_POINTER_binary_predicate</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">predicate</span><span class="plain">);</span>
<span class="identifier">pt0</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">terms</span><span class="plain">[0]; </span><span class="identifier">pt1</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[1];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> == </span><span class="identifier">R_equality</span><span class="plain">) {</span>
<span class="reserved">pcalc_func</span><span class="plain"> *</span><span class="identifier">the_fn</span><span class="plain"> = </span><span class="identifier">pt0</span><span class="plain">.</span><span class="element">function</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">side</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">the_fn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">the_fn</span><span class="plain"> = </span><span class="identifier">pt1</span><span class="plain">.</span><span class="element">function</span><span class="plain">; </span><span class="identifier">side</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">the_fn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[</span><span class="identifier">side</span><span class="plain">].</span><span class="element">function</span><span class="plain">) || (</span><span class="identifier">the_fn</span><span class="plain">-&gt;</span><span class="element">fn_of</span><span class="plain">.</span><span class="element">function</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
<span class="string">"that is too complicated an assertion"</span><span class="plain">,</span>
<span class="string">"and cannot be declared as part of the initial situation. (It "</span>
<span class="string">"does make sense, and could be tested with 'if' - it's just "</span>
<span class="string">"too difficult to get right as an instruction about the starting "</span>
<span class="string">"situation."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">the_fn</span><span class="plain">-&gt;</span><span class="element">bp</span><span class="plain">; </span><span class="identifier">pt0</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[</span><span class="identifier">side</span><span class="plain">]; </span><span class="identifier">pt1</span><span class="plain"> = </span><span class="identifier">the_fn</span><span class="plain">-&gt;</span><span class="element">fn_of</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_11">&#167;9.11</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>As we've already seen, we have to be cautious about the mechanism to draw
inferences about kinds based on the relationships which objects have. Some
cases are easy: if A is worn by B, then B is a person. But "in" can be
very problematic. When one region is in another, we want to suppress any
inferences which might wrongly be drawn about "in": this is a different
kind of containment from the three-dimensional spatial one suggested by
containers and rooms. It also complicates things that a backdrop can be
"in" a region. So we play very safe and make no guesses about regions or
the first term of <code class="display"><span class="extract">R_regional_containment</span></code>.
</p>
<p class="inwebparagraph">We also never deduce "thing" as the kind by this mechanism. This is
because instances of "object" with no apparent declared kind are made into
things by default when we complete the model world anyway; so there is no
need to risk setting the kind here at this stage.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::cautiously_set_kind</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">inst</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">inst</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">k</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">K_thing</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">instance_wo</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">inst</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">instance_wo</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="functiontext">Instances::set_kind</span><span class="plain">(</span><span class="identifier">instance_wo</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::cautiously_set_kind is used in <a href="#SP9_11">&#167;9.11</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Evaluating terms. </b>In asserting a proposition, we are in effect acting as an interpreter rather
than a compiler. Given any term, we need to produce either an object O or a
more general value V. Recall that a term can be
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) a constant C,
</li><li>(b) a variable v, or
</li><li>(c) a function f_R(t) for another term t.
</li></ul>
<p class="inwebparagraph">We are unable, at compile-time, to evaluate f_R(t) for any relation R,
and won't even try. We can evaluate a variable using the interpretation
slate &mdash; that was its whole purpose. So the only case left is a constant:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Calculus::Propositions::Assert::spec_of_term</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">function</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">variable</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">current_interpretation_as_spec</span><span class="plain">[</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">variable</span><span class="plain">];</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">.</span><span class="identifier">constant</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::spec_of_term is used in <a href="#SP9_10">&#167;9.10</a>, <a href="#SP9_11">&#167;9.11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>The analogous routine to extract an instance, which normally takes
precedence, is more convoluted. First, we could be looking at the name of a
kind &mdash; in "A door is usually closed", "door" will appear here as a
description node, and we need to extract the instance of the kind as our
return value. Second, we want to divert all assertions about "the player" so
that they refer to the player object, not to the global variable "the player".
</p>
<p class="inwebparagraph">Users tend to expect that they can talk about properties of things as
values, when setting up the world, and since a property value might be
an object, we are going to be careful to reject a <code class="display"><span class="extract">PROPERTY_VALUE_NT</span></code>
type with a problem message. In practice the A-parser gets there first,
but just in case.
</p>
<pre class="display">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">Calculus::Propositions::Assert::subject_of_term</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">function</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">variable</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">current_interpretation_as_infs</span><span class="plain">[</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">variable</span><span class="plain">];</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">.</span><span class="element">constant</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">InferenceSubjects::from_specification</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Descriptions::to_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="functiontext">Descriptions::to_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">)) {</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">diversion</span><span class="plain"> =</span>
<span class="functiontext">NonlocalVariables::get_alias</span><span class="plain">(</span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">diversion</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">diversion</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::subject_of_term is used in <a href="#SP9_6">&#167;9.6</a>, <a href="#SP9_7">&#167;9.7</a>, <a href="#SP9_8">&#167;9.8</a>, <a href="#SP9_9">&#167;9.9</a>, <a href="#SP9_10">&#167;9.10</a>, <a href="#SP9_11">&#167;9.11</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Testing at compile-time. </b>We can, to a more limited extent, also test whether a given proposition is true
of a given inference subject at the current stage of the world model. (This is
necessary for the implications code to work.)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::testable_at_compile_time</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">KIND_ATOM:</span><span class="plain"> </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PREDICATE_ATOM:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">: </span>&lt;<span class="cwebmacro">See if this unary predicate can be tested</span> <span class="cwebmacronumber">13.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">2</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">default:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::testable_at_compile_time is used in <a href="#SP14">&#167;14</a>, 9/imp (<a href="9-imp.html#SP4_2_2">&#167;4.2.2</a>).</p>
<p class="inwebparagraph"><a id="SP13_1"></a><b>&#167;13.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">See if this unary predicate can be tested</span> <span class="cwebmacronumber">13.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">ale</span><span class="plain"> = </span><span class="identifier">RETRIEVE_POINTER_adjective_usage</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">predicate</span><span class="plain">);</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::get_aph</span><span class="plain">(</span><span class="identifier">ale</span><span class="plain">);</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::has_EORP_meaning</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP13">&#167;13</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>And the actual test:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Propositions::Assert::test_at_compile_time</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">about</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::Assert::testable_at_compile_time</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">;</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">element</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">KIND_ATOM:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Test if this kind atom is true</span> <span class="cwebmacronumber">14.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PREDICATE_ATOM:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">: </span>&lt;<span class="cwebmacro">Test if this unary predicate is true</span> <span class="cwebmacronumber">14.2</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Assert::test_at_compile_time is used in 9/imp (<a href="9-imp.html#SP7_1">&#167;7.1</a>).</p>
<p class="inwebparagraph"><a id="SP14_1"></a><b>&#167;14.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Test if this kind atom is true</span> <span class="cwebmacronumber">14.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_2"></a><b>&#167;14.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Test if this unary predicate is true</span> <span class="cwebmacronumber">14.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">ale</span><span class="plain"> = </span><span class="identifier">RETRIEVE_POINTER_adjective_usage</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">predicate</span><span class="plain">);</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::get_aph</span><span class="plain">(</span><span class="identifier">ale</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::get_parity</span><span class="plain">(</span><span class="identifier">ale</span><span class="plain">);</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::has_EORP_meaning</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain">) {</span>
<span class="reserved">possession_marker</span><span class="plain"> *</span><span class="identifier">adj</span><span class="plain"> = </span><span class="functiontext">Properties::get_possession_marker</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">adj</span><span class="plain">-&gt;</span><span class="element">possessed</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">adj</span><span class="plain">-&gt;</span><span class="element">possessed</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="12-qr.html">Back to 'Quasinumeric Relations'</a></li><li><a href="12-is.html">Continue with 'I6 Schemas'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>