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/9-pk.html
2019-04-22 15:42:10 +01:00

432 lines
46 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>9/ma</title>
<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>
<!--Weave of '9/pk' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#9">Chapter 9: The A-Parser</a></li><li><b>Property Knowledge</b></li></ul><p class="purpose">This section draws inferences from assertions which seem to be about the properties of things, independent of their location.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Asserting global variable values</a></li><li><a href="#SP3">&#167;3. Asserting properties, three different ways</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Asserting global variable values. </b>A global like "score" is in effect a property belonging to no single object,
and which therefore exists only once.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::PropertyKnowledge::initialise_global_variable</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="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) {</span>
<span class="functiontext">Assertions::PropertyKnowledge::igv_dash</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::PropertyKnowledge::verify_global_variable</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="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">init</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_initial_value</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">init</span><span class="plain">) </span><span class="functiontext">Assertions::PropertyKnowledge::igv_dash</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">, </span><span class="identifier">init</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 Assertions::PropertyKnowledge::initialise_global_variable is used in 9/ma (<a href="9-ma.html#SP3_3_41_3">&#167;3.3.41.3</a>).</p>
<p class="endnote">The function Assertions::PropertyKnowledge::verify_global_variable is used in 5/nv (<a href="5-nv.html#SP16">&#167;16</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::PropertyKnowledge::igv_dash</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="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">verification_stage</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to initialise null variable"</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_as_declared</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::kind</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">constant_kind</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">outcome</span><span class="plain"> = </span><span class="identifier">Kinds::Compare::compatible</span><span class="plain">(</span><span class="identifier">constant_kind</span><span class="plain">, </span><span class="identifier">kind_as_declared</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">throw_problem</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">outcome</span><span class="plain"> == </span><span class="identifier">NEVER_MATCH</span><span class="plain">) </span><span class="identifier">throw_problem</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">verification_stage</span><span class="plain">) &amp;&amp; (</span><span class="identifier">outcome</span><span class="plain"> == </span><span class="identifier">SOMETIMES_MATCH</span><span class="plain">)) </span><span class="identifier">throw_problem</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">throw_problem</span><span class="plain">)</span>
&lt;<span class="cwebmacro">The value doesn't match the kind of the variable</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="character">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verification_stage</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">var</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">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Abstract::to_set_relation</span><span class="plain">(</span><span class="identifier">R_equality</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::PropertyKnowledge::igv_dash is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b>On the face of it, the following looks unnecessary, and it nearly is.
</p>
<p class="inwebparagraph">It looks unnecessary because the proposition machinery will later typecheck
what we ask it to do anyway. That will indeed throw out sentences like:
</p>
<blockquote>
<p>The tally is a number that varies. The tally is the Entire Game.</p>
</blockquote>
<p class="inwebparagraph">But it will do this by rejecting a comparison between "tally" and "Entire
Game", and the problem message will thus be slightly vague, and not make
clear that Inform realises we were trying to set a variable. More seriously,
</p>
<blockquote>
<p>The zone is a room that varies. The zone is nothing.</p>
</blockquote>
<p class="inwebparagraph">would not be rejected by the proposition machinery, because it's legal to
compare "zone" and "nothing"; it's only illegal to assert that they are
equal. So the proposition has to pass typechecking.
</p>
<p class="inwebparagraph">For both these reasons, then, we perform a simple type-check here.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">The value doesn't match the kind of the variable</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Variable: $u; constant: $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">kind_as_declared</span><span class="plain">, </span><span class="identifier">constant_kind</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">q</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">kind_as_declared</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(5, </span><span class="identifier">constant_kind</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">kind_as_declared</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Rvalues::is_nothing_object_constant</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_QuantityKindNothing</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 tells me that '%2', which should be %4 that varies, is to "</span>
<span class="string">"have the initial value 'nothing'. This is allowed as an 'object which varies', "</span>
<span class="string">"but the rules are stricter for %4."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_GlobalKindWrong</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 tells me that '%2', which is %4 that varies, "</span>
<span class="string">"should start out with the value '%3', but this is %5 and not %4."</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">constant_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(!</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">kind_as_declared</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)))</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">" %PIn sentences like this, when I can't understand some text, "</span>
<span class="string">"I often assume that it's meant to be a new object. So it may "</span>
<span class="string">"be that you intended '%3' to be something quite different, "</span>
<span class="string">"but I just didn't get it."</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::diagnose_further</span><span class="plain">();</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</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="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Asserting properties, three different ways. </b>In these three alternative routines, we can assert that a given owner &mdash; specified
either as an object, a value or a subtree &mdash; should have
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) a given single property equal to a value given as a subtree,
</li><li>(b) a given single property equal to an explicit value, or
</li><li>(c) a whole list of properties and their values.
</li></ul>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::PropertyKnowledge::assert_property_value_from_property_subtree_infs</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="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val_subtree</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="functiontext">Calculus::Propositions::Abstract::from_property_subtree</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">val_subtree</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem for an unrecognised property owner</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="plain">;</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">owner</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::PropertyKnowledge::assert_property_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner_subtree</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">list_subtree</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Check that the owner subtree isn't dangerously elaborate</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="character">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">owner_subtree</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner_spec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">owner_subtree</span><span class="plain">)))</span>
<span class="identifier">owner_spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">owner_spec</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Descriptions::is_qualified</span><span class="plain">(</span><span class="identifier">owner_spec</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="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">owner_spec</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">owner</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="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem for an unrecognised property owner</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_clue</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Work out the clue kind</span> <span class="cwebmacronumber">3.1</span>&gt;<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="functiontext">Calculus::Propositions::Abstract::from_property_list</span><span class="plain">(</span><span class="identifier">list_subtree</span><span class="plain">, </span><span class="identifier">kind_clue</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">owner</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::PropertyKnowledge::assert_property_value_from_property_subtree_infs is used in 9/ma (<a href="9-ma.html#SP3_3_13">&#167;3.3.13</a>, <a href="9-ma.html#SP3_3_26">&#167;3.3.26</a>, <a href="9-ma.html#SP3_3_41">&#167;3.3.41</a>, <a href="9-ma.html#SP3_3_41_4">&#167;3.3.41.4</a>, <a href="9-ma.html#SP3_3_41_5">&#167;3.3.41.5</a>), 19/tod (<a href="19-tod.html#SP6_4_3_1">&#167;6.4.3.1</a>).</p>
<p class="endnote">The function Assertions::PropertyKnowledge::assert_property_list is used in 9/tc (<a href="9-tc.html#SP5_2_1">&#167;5.2.1</a>), 9/ma (<a href="9-ma.html#SP3_3_18">&#167;3.3.18</a>, <a href="9-ma.html#SP3_3_29">&#167;3.3.29</a>, <a href="9-ma.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b>We pass the "clue kind" to obtain a proposition which includes an atom
setting the kind of the free variable &mdash; not because we need to assert this,
although it does no harm to, but because this enables the proposition
asserter to know the kind of the free variable, which in turn affects the
interpretation placed on adjectives which have different meanings in different
domains. (Within "object", we needn't narrow down, though, because adjectives
are typechecked at run-time rather than compile-time in that domain.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out the clue kind</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner</span><span class="plain">) {</span>
<span class="identifier">kind_clue</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kind_clue</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">kind_clue</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="functiontext">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">InferenceSubjects::is_an_object</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">InferenceSubjects::is_a_kind_of_object</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">)))</span>
<span class="identifier">kind_clue</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that the owner subtree isn't dangerously elaborate</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner_spec</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">owner_subtree</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">owner_spec</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Calculus::Propositions::contains_binary_predicate</span><span class="plain">(</span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">owner_spec</span><span class="plain">))) ||</span>
<span class="plain">(</span><span class="functiontext">Descriptions::number_of_adjectives_applied_to</span><span class="plain">(</span><span class="identifier">owner_spec</span><span class="plain">) &gt; 0) ||</span>
<span class="plain">(</span><span class="functiontext">Calculus::Propositions::contains_adjective</span><span class="plain">(</span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">owner_spec</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="functiontext">Problems::quote_spec</span><span class="plain">(2, </span><span class="identifier">owner_spec</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelationAPL</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 looked to me as if it might be trying to assign certain "</span>
<span class="string">"properties to something described in a way (%2) which involved a clause "</span>
<span class="string">"which can't be properly determined until the game is running, so that at "</span>
<span class="string">"this point it's impossible to act upon."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</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="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for an unrecognised property owner</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<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::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropForBadKOV</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 looked to me as if it might be trying to assign certain properties "</span>
<span class="string">"to something which is not allowed to have them."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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="#SP3">&#167;3</a> (twice).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The following assumes that the subtree <code class="display"><span class="extract">py</span></code> describes a value which the
<code class="display"><span class="extract">prn</span></code> property of something will have; it issues problem messages if this
would be impossible, returning <code class="display"><span class="extract">NULL</span></code>, or else silently returns the value.
It's used both above and by the tree-conversion code in the predicate
calculus engine.
</p>
<p class="inwebparagraph">Here there's no need to perform any typechecking; all of that is done by
the proposition machinery.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Assertions::PropertyKnowledge::property_value_from_property_subtree</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="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::is_either_or</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">py</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem, as this uses a bare adjective as if a value-property</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Issue a problem, as this makes sense only for value properties</span> <span class="cwebmacronumber">4.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Check that the subtree does indeed express a property value</span> <span class="cwebmacronumber">4.3</span>&gt;<span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::substitute_constants</span><span class="plain">(</span>
<span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">));</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">property_kind</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::kind</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="functiontext">ParseTreeUsage::is_value</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem for a property value which isn't a constant</span> <span class="cwebmacronumber">4.4</span>&gt;<span class="character">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">val</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::PropertyKnowledge::property_value_from_property_subtree is used in 11/tc (<a href="11-tc.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem, as this uses a bare adjective as if a value-property</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(3, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_HasBareAdjective</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1 you write about the %3 property as if it were some kind of value "</span>
<span class="string">"or possession, but %3 is an either/or property - something is either "</span>
<span class="string">"%3 or not. (For example, it's incorrect to say 'The glass box has "</span>
<span class="string">"transparent'; the right way is just 'The glass box is transparent.')"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem, as this makes sense only for value properties</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(3, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</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="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1 you give a value of the %3 property as '%2', but %3 is an either/or "</span>
<span class="string">"property - something is either %3 or not, so there is no value involved."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_3"></a><b>&#167;4.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that the subtree does indeed express a property value</span> <span class="cwebmacronumber">4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Assertions::Refiner::coerce_adjectival_usage_to_noun</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">), </span><span class="constant">UNKNOWN_NT</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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(3, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyValueUnknown</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but that seems to set a property %3 to the "</span>
<span class="string">"value '%2', which I don't recognise as meaning anything."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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>
<span class="reserved">break</span><span class="plain">; </span> <span class="comment">(this is fine &mdash; there's a well-expressed value)</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COMMON_NOUN_NT</span><span class="plain">:</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyInstance</span><span class="plain">),</span>
<span class="string">"this property value makes no sense to me"</span><span class="plain">,</span>
<span class="string">"since it looks as if it contains a relative clause. Sometimes this "</span>
<span class="string">"happens if a clause follows directly on, and I have misunderstood to "</span>
<span class="string">"what it belongs. For instance: 'The widget is a door with matching "</span>
<span class="string">"key a thing in the Ballroom' is read with 'a thing in the Ballroom' as "</span>
<span class="string">"the value of the 'matching key' property, not with 'in the Ballroom' "</span>
<span class="string">"applying to the door."</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">case</span><span class="plain"> </span><span class="constant">X_OF_Y_NT</span><span class="plain">:</span>
<span class="identifier">Problems::Issue::sentence_problem</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">"something grammatically odd has happened here"</span><span class="plain">,</span>
<span class="string">"possibly to do with the unexpected 'of' in what seems to be a list of "</span>
<span class="string">"property values?"</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">case</span><span class="plain"> </span><span class="identifier">WITH_NT</span><span class="plain">:</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_MisplacedFrom</span><span class="plain">),</span>
<span class="string">"something grammatically odd has happened here"</span><span class="plain">,</span>
<span class="string">"possibly to do with the unexpected 'with' in what seems "</span>
<span class="string">"to be a list of property values? Maybe there is some punctuation missing."</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">default</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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(3, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PeculiarPropertyValue</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but that seems to set a property %3 to the "</span>
<span class="string">"value '%2', which really doesn't make sense."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_4"></a><b>&#167;4.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for a property value which isn't a constant</span> <span class="cwebmacronumber">4.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">property_kind</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(4, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyNonConstant</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1 you give a value of the %4 property as '%2', "</span>
<span class="string">"and while this does make sense as %3, it is a value which "</span>
<span class="string">"exists and changes during play, and which doesn't make sense to "</span>
<span class="string">"use when setting up the initial state of things."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="9-ma.html">Back to 'Make Assertions'</a></li><li><a href="9-rk.html">Continue with 'Relation Knowledge'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>