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

1417 lines
142 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>9/tbath</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/rpt' 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>Refine Parse Tree</b></li></ul><p class="purpose">To determine which subjects are referred to by noun phrases such as "the table" and "a paper cup" found in assertion sentences being parsed.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. How individual nouns are represented after refinement</a></li><li><a href="#SP5">&#167;5. Representation of single adjectives</a></li><li><a href="#SP7">&#167;7. The refinery itself</a></li><li><a href="#SP11">&#167;11. About surgeries</a></li><li><a href="#SP12">&#167;12. And surgery</a></li><li><a href="#SP13">&#167;13. With surgery</a></li><li><a href="#SP14">&#167;14. Location surgery</a></li><li><a href="#SP15">&#167;15. Called surgery</a></li><li><a href="#SP16">&#167;16. The player is not yourself</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. How individual nouns are represented after refinement. </b>The parse tree identifies the primary verb in each sentence, but does only the
most basic work in parsing its noun phrases. It can spot the use of certain
keywords like "called", and constructions like "kind of", but otherwise the
NPs are just left unparsed.
</p>
<p class="inwebparagraph">Here we "refine" the subtree for a single noun phrase. Refinement means that
we either annotate it with a meaning or break it down into subtree of further
nodes, thus decomposing the NP into smaller clauses which are refined in turn.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</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="functiontext">Assertions::Refiner::pn_make_COMMON_or_PROPER</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_evaluation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext">InferenceSubjects::as_constant</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</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="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</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="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">spec</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">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">spec</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">Calculus::Propositions::describes_value</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">val</span><span class="plain">) </span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::from_specification</span><span class="plain">(</span><span class="identifier">val</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">Calculus::Variables::kind_of_variable_0</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">Kinds::Compare::lt</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">FALSE</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">infs</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="functiontext">Assertions::Refiner::pn_noun_details_from_spec</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">infs</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="functiontext">Assertions::Refiner::pn_make_COMMON_or_PROPER</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_evaluation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::noun_from_infs is used in <a href="#SP9_5_1">&#167;9.5.1</a>, <a href="#SP9_7_4">&#167;9.7.4</a>, <a href="#SP10_1">&#167;10.1</a>, <a href="#SP16">&#167;16</a>, 9/tc (<a href="9-tc.html#SP5_4">&#167;5.4</a>, <a href="9-tc.html#SP8_4">&#167;8.4</a>, <a href="9-tc.html#SP8_4_1">&#167;8.4.1</a>), 9/ass (<a href="9-ass.html#SP14">&#167;14</a>).</p>
<p class="endnote">The function Assertions::Refiner::noun_from_value is used in <a href="#SP6">&#167;6</a>, <a href="#SP9_7_6">&#167;9.7.6</a>, <a href="#SP9_7_6_5">&#167;9.7.6.5</a>, 9/tc (<a href="9-tc.html#SP5_4">&#167;5.4</a>, <a href="9-tc.html#SP5_4_1_1">&#167;5.4.1.1</a>), 9/ma (<a href="9-ma.html#SP3_3_11">&#167;3.3.11</a>, <a href="9-ma.html#SP5">&#167;5</a>), 9/rk (<a href="9-rk.html#SP2">&#167;2</a>), 19/tb (<a href="19-tb.html#SP25_1">&#167;25.1</a>), 19/tod (<a href="19-tod.html#SP6_3">&#167;6.3</a>, <a href="19-tod.html#SP6_4_3_1">&#167;6.4.3.1</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Furthermore:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(c) If the noun phrase gives a number of items, the <code class="display"><span class="extract">multiplicity</span></code> annotation
records how many; thus, for "six lorries" it would be 6.
</li><li>(d) If the noun phrase describes some properties or relations which must be
true &mdash; "an open door", say, or "a woman in London" &mdash; these are recorded
in a <code class="display"><span class="extract">creation_proposition</span></code> field.
</li></ul>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::pn_noun_details_from_spec</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</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="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Descriptions::get_quantified_prop</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_creation_proposition</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext">Calculus::Propositions::copy</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">N</span><span class="plain"> = </span><span class="functiontext">Descriptions::get_quantification_parameter</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">N</span><span class="plain"> &gt; 0) </span><span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">multiplicity_ANNOT</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::pn_noun_details_from_spec is used in <a href="#SP1">&#167;1</a>, <a href="#SP5">&#167;5</a>, <a href="#SP10_1">&#167;10.1</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>And lastly:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(e) The node type is <code class="display"><span class="extract">COMMON_NOUN_NT</span></code> if and only if the <code class="display"><span class="extract">subject</span></code> field is
an inference subject representing a domain rather than a single instance;
thus, if it is kind of object or a kind of value. In all other cases, the
node type is <code class="display"><span class="extract">PROPER_NOUN_NT</span></code>.
</li></ul>
<p class="inwebparagraph">The linguistic difference between proper and common nouns is a matter of some
disagreement among semanticists, but to us it's very helpful in distinguishing
cases in the assertion-maker.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::pn_make_COMMON_or_PROPER</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</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">if</span><span class="plain"> ((</span><span class="identifier">infs</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">))) </span><span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">COMMON_NOUN_NT</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::pn_make_COMMON_or_PROPER is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>It's useful to have a safe way of transferring the complete noun details
from one node to another, without breaking the above invariant. (The
<code class="display"><span class="extract">nowhere</span></code> annotation is used by the spatial model plugin, if active, and
it probably never needs to be copied, but we do so for safety's sake.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::copy_noun_details</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_evaluation</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_creation_proposition</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">ParseTree::get_creation_proposition</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">));</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="constant">multiplicity_ANNOT</span><span class="plain">, </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="constant">multiplicity_ANNOT</span><span class="plain">));</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="constant">nowhere_ANNOT</span><span class="plain">, </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="constant">nowhere_ANNOT</span><span class="plain">));</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="constant">creation_site_ANNOT</span><span class="plain">, </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="constant">creation_site_ANNOT</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::copy_noun_details is used in 19/tb (<a href="19-tb.html#SP28">&#167;28</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Representation of single adjectives. </b>Individual adjective nodes are made as follows. Note that we append noun
details to the nodes so that sentences like this one...
</p>
<blockquote>
<p>Scenery is usually fixed in place.</p>
</blockquote>
<p class="inwebparagraph">...can work; here "scenery", though an adjective, is effectively a common
noun in disguise. (It's a deficiency of English that a surprising number of
common things, which ought to have count nouns, in fact have mass nouns &mdash;
compare "clothing" and "clothes", which has no adequate singular.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::pn_make_adjective</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">ale</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">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="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">ADJECTIVE_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_aph</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">aph</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_evaluation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::pn_noun_details_from_spec</span><span class="plain">(</span><span class="identifier">p</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">AdjectiveUsages::get_parity</span><span class="plain">(</span><span class="identifier">ale</span><span class="plain">)) </span><span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">negated_boolean_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">negated_boolean_ANNOT</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::Refiner::pn_make_adjective is used in <a href="#SP10_3">&#167;10.3</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>A different reason why adjective and nouns overlap is due to words like
"green", which describe a state and also suggest that something possesses it.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::coerce_adjectival_usage_to_noun</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">leaf</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">) == </span><span class="constant">ADJECTIVE_NT</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="functiontext">Adjectives::Meanings::has_ENUMERATIVE_meaning</span><span class="plain">(</span><span class="identifier">ParseTree::get_aph</span><span class="plain">(</span><span class="identifier">leaf</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="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::coerce_adjectival_usage_to_noun is used in 9/ma (<a href="9-ma.html#SP3_3_22">&#167;3.3.22</a>, <a href="9-ma.html#SP3_3_26">&#167;3.3.26</a>), 9/pk (<a href="9-pk.html#SP4_3">&#167;4.3</a>), 9/rk (<a href="9-rk.html#SP3_1">&#167;3.1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. The refinery itself. </b>Time to get started, then. Each subtree can be refined only once.
</p>
<p class="inwebparagraph">The <code class="display"><span class="extract">creation_rule</span></code> can have three values:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">FORBID_CREATION</span><span class="plain"> 0 </span> <span class="comment">never create an object with this name</span>
<span class="definitionkeyword">define</span> <span class="constant">ALLOW_CREATION</span><span class="plain"> 1 </span> <span class="comment">create an object with this name if that looks sensible</span>
<span class="definitionkeyword">define</span> <span class="constant">MANDATE_CREATION</span><span class="plain"> 2 </span> <span class="comment">always create an object with this name, except for "it"</span>
</pre>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">forbid_nowhere</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">creation_rule</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</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">"Refine parse tree on null pn"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">NOUN_RESOLUTION</span><span class="plain">, </span><span class="string">"Refine subtree (%s creation):\</span><span class="plain">n</span><span class="string">$T"</span><span class="plain">,</span>
<span class="plain">((</span><span class="identifier">creation_rule</span><span class="plain"> == </span><span class="constant">FORBID_CREATION</span><span class="plain">)?</span><span class="string">"forbid"</span><span class="plain">:</span>
<span class="plain">((</span><span class="identifier">creation_rule</span><span class="plain"> == </span><span class="constant">ALLOW_CREATION</span><span class="plain">)?</span><span class="string">"allow"</span><span class="plain">:</span><span class="string">"mandate"</span><span class="plain">)), </span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">LOG_INDENT</span><span class="plain">;</span>
<span class="functiontext">Assertions::Refiner::refine_parse_tree_inner</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">creation_rule</span><span class="plain">);</span>
<span class="identifier">LOG_OUTDENT</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">NOUN_RESOLUTION</span><span class="plain">, </span><span class="string">"Refined subtree is:\</span><span class="plain">n</span><span class="string">$T"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::refine is used in <a href="#SP9_1">&#167;9.1</a>, <a href="#SP9_2">&#167;9.2</a>, <a href="#SP9_2_1">&#167;9.2.1</a>, <a href="#SP9_3">&#167;9.3</a>, <a href="#SP9_4">&#167;9.4</a>, <a href="#SP9_5">&#167;9.5</a>, <a href="#SP9_6">&#167;9.6</a>, <a href="#SP9_7_3">&#167;9.7.3</a>, 9/tbath (<a href="9-tbath.html#SP5">&#167;5</a>), 9/pd (<a href="9-pd.html#SP5">&#167;5</a>), 11/tc (<a href="11-tc.html#SP7_1">&#167;7.1</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>What we do depends on the crude structure already found.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::refine_parse_tree_inner</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">creation_rule</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">p</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>&lt;<span class="cwebmacro">Refine an X-of-Y subtree</span> <span class="cwebmacronumber">9.1</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">WITH_NT</span><span class="plain">: </span>&lt;<span class="cwebmacro">Refine an X-with-Y subtree</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">AND_NT</span><span class="plain">: </span>&lt;<span class="cwebmacro">Refine an X-and-Y subtree</span> <span class="cwebmacronumber">9.3</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">RELATIONSHIP_NT</span><span class="plain">: </span>&lt;<span class="cwebmacro">Refine a relationship subtree</span> <span class="cwebmacronumber">9.5</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">CALLED_NT</span><span class="plain">: </span>&lt;<span class="cwebmacro">Refine a calling subtree</span> <span class="cwebmacronumber">9.4</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">KIND_NT</span><span class="plain">: </span>&lt;<span class="cwebmacro">Refine a kind subtree</span> <span class="cwebmacronumber">9.6</span>&gt;<span class="plain">; </span><span class="reserved">return</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>&lt;<span class="cwebmacro">Refine what seems to be a noun phrase</span> <span class="cwebmacronumber">9.7</span>&gt;<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">The function Assertions::Refiner::refine_parse_tree_inner is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>Recall that an <code class="display"><span class="extract">X_OF_Y_NT</span></code> subtree has the form owner followed by
property name, so we forbid creation of a new object from the property name
subtree.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine an X-of-Y subtree</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">creation_rule</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="constant">FORBID_CREATION</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><code class="display"><span class="extract">WITH_NT</span></code> is used to create something with a list of properties. This
leads to some awkward cases &mdash; for instance, where a "with" in an action
pattern like "doing something with the bucket" has been misinterpreted.
We fix those cases by hand, by reconstructing the text before it was
divided, to form the word range (a_1, a_2); then parsing it as an action
pattern; if it works, that reading is allowed to stand.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine an X-with-Y subtree</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">creation_rule</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::perform_with_surgery</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">WITH_NT</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">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">)),</span>
<span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">)));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">pattern</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">ACTION_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_action_meaning</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;);</span>
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Start the refinement over</span> <span class="cwebmacronumber">9.2.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_2_1"></a><b>&#167;9.2.1. </b>After surgery on the tree, it's usually best to start over again:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Start the refinement over</span> <span class="cwebmacronumber">9.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">creation_rule</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_2">&#167;9.2</a>, <a href="#SP9_4">&#167;9.4</a>, <a href="#SP9_5">&#167;9.5</a>.</p>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b><code class="display"><span class="extract">AND_NT</span></code> is easy, except for "and surgery", of which more below.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine an X-and-Y subtree</span> <span class="cwebmacronumber">9.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">creation_rule</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="identifier">creation_rule</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::perform_and_surgery</span><span class="plain">(</span><span class="identifier">p</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>A <code class="display"><span class="extract">CALLED_NT</span></code> node has two children: in the phrase "an X called Y", they
will represent X and Y respectively. Y must be created afresh whatever its
name, since the whole point of "called" is that it enables the designer
to use names which would otherwise be interpreted as meaning something
significant: it is a sort of literal escape, like the backslash character
in C strings. X is never something new: it is expected to be a kind.
We convert the whole node into a simple <code class="display"><span class="extract">PROPER_NOUN_NT</span></code> with the name
of Y and the kind of X. In this way, all <code class="display"><span class="extract">CALLED_NT</span></code> nodes are removed
from the tree.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine a calling subtree</span> <span class="cwebmacronumber">9.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) == </span><span class="identifier">RELATIONSHIP_NT</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">)) {</span>
<span class="functiontext">Assertions::Refiner::perform_called_surgery</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Start the refinement over</span> <span class="cwebmacronumber">9.2.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="constant">FORBID_CREATION</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="constant">multiplicity_ANNOT</span><span class="plain">) &gt; 1) {</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_MultipleCalled</span><span class="plain">),</span>
<span class="string">"I can only make a single 'called' thing at a time"</span><span class="plain">,</span>
<span class="string">"or rather, the 'called' is only allowed to apply to one thing "</span>
<span class="string">"at a time. For instance, 'A thing called a vodka and tonic is "</span>
<span class="string">"on the table.' is allowed, but 'Two things called vodka and tonic' "</span>
<span class="string">"is not."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">forbid_nowhere</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">creation_rule</span><span class="plain"> == </span><span class="constant">FORBID_CREATION</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">"'called' can't be used in this context"</span><span class="plain">,</span>
<span class="string">"and is best reserved for full sentences."</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="constant">MANDATE_CREATION</span><span class="plain">);</span>
<span class="identifier">forbid_nowhere</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="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_5"></a><b>&#167;9.5. </b>A <code class="display"><span class="extract">RELATIONSHIP_NT</span></code> node may have no children, representing "here"; or
it may have one child, a room or door which lies in some map direction. But
in general it has two children: for instance "a green marble in a blue box"
has the marble and the box as its children, the relationship being containment.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine a relationship subtree</span> <span class="cwebmacronumber">9.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Assertions::Refiner::perform_location_surgery</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">AND_NT</span><span class="plain">) </span>&lt;<span class="cwebmacro">Start the refinement over</span> <span class="cwebmacronumber">9.2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">creation_rule</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">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">ParseTree::get_relationship</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">dir</span><span class="plain"> = </span><span class="identifier">PL::MapDirections::get_mapping_direction</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::get_reversal</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dir</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">dir</span><span class="plain"> = </span><span class="identifier">PL::MapDirections::get_mapping_direction</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dir</span><span class="plain">) </span>&lt;<span class="cwebmacro">Make the relation one which refers to a map direction</span> <span class="cwebmacronumber">9.5.1</span>&gt;<span class="plain">;</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="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) </span><span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="identifier">creation_rule</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_1"></a><b>&#167;9.5.1. </b>This handles the case of a one-child node representing a map direction,
but fills in a second child as the direction object in question. Thus if
the relation is mapped-north-of, then the second child will become the
direction object for "north".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Make the relation one which refers to a map direction</span> <span class="cwebmacronumber">9.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">NOUN_RESOLUTION</span><span class="plain">, </span><span class="string">"Directional predicate with BP %S ($O)\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::get_log_name</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">), </span><span class="identifier">dir</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">relationship_node_type_ANNOT</span><span class="plain">, </span><span class="identifier">DIRECTION_RELN</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">DW</span><span class="plain"> = </span><span class="functiontext">Instances::get_name</span><span class="plain">(</span><span class="identifier">dir</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">DW</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="identifier">dir</span><span class="plain">));</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</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. </b>A <code class="display"><span class="extract">KIND_NT</span></code> node may have no children, and if so it represents the bare
word "kind": the reference must be to the kind "kind" itself.
Otherwise it has one child &mdash; the name of an existing kind of value or
object. After refinement, it will be annotated with a valid non-null
inference subject representing the domain to which any new kind would belong.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine a kind subtree</span> <span class="cwebmacronumber">9.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">kind_of_what</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_object</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">what</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">what</span><span class="plain">, </span><span class="constant">FORBID_CREATION</span><span class="plain">);</span>
<span class="identifier">kind_of_what</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">what</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">kind_of_what</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">kind_of_what</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem message for a kind of instance</span> <span class="cwebmacronumber">9.6.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">InferenceSubjects::as_nonobject_kind</span><span class="plain">(</span><span class="identifier">kind_of_what</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">kind_of_what</span><span class="plain"> != </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">kind_of_what</span><span class="plain"> != </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_object</span><span class="plain">)))</span>
&lt;<span class="cwebmacro">Issue a problem message for a disallowed subkind</span> <span class="cwebmacronumber">9.6.2</span>&gt;<span class="plain">;</span>
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">kind_of_what</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_6_1"></a><b>&#167;9.6.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for a kind of instance</span> <span class="cwebmacronumber">9.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">InferenceSubjects::is_an_object</span><span class="plain">(</span><span class="identifier">kind_of_what</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">kind_of_what</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_KindOfInstance</span><span class="plain">),</span>
<span class="string">"kinds can only be made from other kinds"</span><span class="plain">,</span>
<span class="string">"so 'a kind of container' is allowed but 'a kind of Mona Lisa' (where "</span>
<span class="string">"Mona Lisa is a specific thing you've already made), wouldn't be "</span>
<span class="string">"allowed. There is only one Mona Lisa."</span><span class="plain">);</span>
<span class="identifier">kind_of_what</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_object</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</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_KindOfActualValue</span><span class="plain">),</span>
<span class="string">"I don't recognise that as a kind"</span><span class="plain">,</span>
<span class="string">"such as 'room' or 'door': it would need to be straightforwardly the name "</span>
<span class="string">"of a kind, and not be qualified with adjectives like 'open'."</span><span class="plain">);</span>
<span class="identifier">kind_of_what</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_value</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_6">&#167;9.6</a>.</p>
<p class="inwebparagraph"><a id="SP9_6_2"></a><b>&#167;9.6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for a disallowed subkind</span> <span class="cwebmacronumber">9.6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<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_KindOfExotica</span><span class="plain">),</span>
<span class="string">"you are only allowed to create kinds of objects (things, rooms, and "</span>
<span class="string">"so on) and kinds of 'value'"</span><span class="plain">,</span>
<span class="string">"so for example 'colour is a kind of value' is allowed but 'prime is "</span>
<span class="string">"a kind of number' is not."</span><span class="plain">);</span>
<span class="identifier">kind_of_what</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_6">&#167;9.6</a>.</p>
<p class="inwebparagraph"><a id="SP9_7"></a><b>&#167;9.7. </b>The simple description of what happens to a <code class="display"><span class="extract">PROPER_NOUN_NT</span></code> node is that
if it's an existing object or value, then it should be annotated with a
reference to that object or value; and if not, then a new object should be
created with that name. (We don't actually create here, though: we just mark
such a noun phrase by changing its node type to <code class="display"><span class="extract">CREATED_NT</span></code>.) The more
complicated description is as follows:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Refine what seems to be a noun phrase</span> <span class="cwebmacronumber">9.7</span>&gt; =
</code></p>
<pre class="displaydefn">
&lt;<span class="cwebmacro">Act on the special no-words word range which implies the player</span> <span class="cwebmacronumber">9.7.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on a newly-discovered property of something</span> <span class="cwebmacronumber">9.7.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on the special noun phrases "it" and "they"</span> <span class="cwebmacronumber">9.7.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">forbid_nowhere</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Act on any special noun phrases significant to plugins</span> <span class="cwebmacronumber">9.7.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">creation_rule</span><span class="plain"> != </span><span class="constant">MANDATE_CREATION</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Interpret this as an existing noun if possible</span> <span class="cwebmacronumber">9.7.6</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">creation_rule</span><span class="plain"> != </span><span class="constant">FORBID_CREATION</span><span class="plain">) </span><span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">CREATED_NT</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">p</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="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_1"></a><b>&#167;9.7.1. </b>There's just one case where an empty word range can be used as a noun
phrase &mdash; when it represents an implicit noun, as here, where the person
doing the carrying is implicit:
</p>
<blockquote>
<p>The black box is carried.</p>
</blockquote>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on the special no-words word range which implies the player</span> <span class="cwebmacronumber">9.7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">implicitly_refers_to_ANNOT</span><span class="plain">)) {</span>
<span class="functiontext">Plugins::Call::refine_implicit_noun</span><span class="plain">(</span><span class="identifier">p</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">Wordings::empty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Tried to resolve malformed noun-phrase"</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_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_2"></a><b>&#167;9.7.2. </b>The following is needed to handle something like "colour of the box",
where "colour" is a property name. We must be careful, though, to avoid
confusion with variable declarations:
</p>
<blockquote>
<p>The interesting var is a description of numbers that varies.</p>
</blockquote>
<p class="inwebparagraph">which would otherwise be misread as an attempt to set the "description"
property of something.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">newfound</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">&gt; ::=</span>
<span class="identifier">in</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="identifier">presence</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> ... | ==&gt; 0; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FAIL_NONTERMINAL</span><span class="plain"> + </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]) - </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">... </span><span class="identifier">that</span><span class="plain"> </span><span class="identifier">varies</span><span class="plain"> | ==&gt; 0; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FAIL_NONTERMINAL</span><span class="plain"> + </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]) - </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">...</span><span class="element"> variable</span><span class="plain"> | ==&gt; 0; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FAIL_NONTERMINAL</span><span class="plain"> + </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]) - </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">{&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">v</span><span class="plain">&gt;} </span><span class="identifier">of</span><span class="plain"> ... ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9_7_3"></a><b>&#167;9.7.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Act on a newly-discovered property of something</span> <span class="cwebmacronumber">9.7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">property</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="identifier">wording</span><span class="plain"> </span><span class="identifier">PW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">OW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">newfound</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) {</span>
<span class="identifier">prn</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">PW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">newfound</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">&gt;, 1);</span>
<span class="identifier">OW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">newfound</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">&gt;, 2);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">prn</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Properties::is_value_property</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) </span>
<span class="plain">(</span><span class="functiontext">Properties::Valued::coincides_with_kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) */) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">NOUN_RESOLUTION</span><span class="plain">, </span><span class="string">"Resolving new-property of: $Y\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">X_OF_Y_NT</span><span class="plain">);</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">&gt;(</span><span class="identifier">OW</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">PW</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">NOUN_RESOLUTION</span><span class="plain">, </span><span class="string">"Resolved new-property to:\</span><span class="plain">n</span><span class="string">$T\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">creation_rule</span><span class="plain">);</span>
<span class="reserved">return</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_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_4"></a><b>&#167;9.7.4. </b>A noun phrase consisting of a pronoun has <code class="display"><span class="extract">refers</span></code> set to the relevant
thing. (If we had more and better pronouns, they would go here.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on the special noun phrases "it" and "they"</span> <span class="cwebmacronumber">9.7.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">nounphrase_article_ANNOT</span><span class="plain">) == </span><span class="identifier">IT_ART</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((&lt;</span><span class="identifier">nominative</span><span class="plain">-</span><span class="identifier">pronoun</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == 2) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Assertions::Traverse::get_current_subject_plurality</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_EnigmaticThey</span><span class="plain">),</span>
<span class="string">"I'm unable to handle 'they' here"</span><span class="plain">,</span>
<span class="string">"since it looks as if it needs to refer to more than one "</span>
<span class="string">"object here, and that's something I can't manage."</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="functiontext">Assertions::Traverse::get_current_object</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="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_EnigmaticPronoun</span><span class="plain">),</span>
<span class="string">"I'm not sure what to make of the pronoun here"</span><span class="plain">,</span>
<span class="string">"since it is unclear what previously mentioned thing "</span>
<span class="string">"is being referred to. In general, it's best only to use "</span>
<span class="string">"'it' where it's unambiguous, and it may be worth noting "</span>
<span class="string">"that 'they' is not allowed to stand for more than one "</span>
<span class="string">"object at a time."</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">referent</span><span class="plain"> = </span><span class="functiontext">Assertions::Traverse::get_current_object</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">referent</span><span class="plain">) </span><span class="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">referent</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PRONOUNS</span><span class="plain">, </span><span class="string">"Interpreting 'it' as $j\</span><span class="plain">n</span><span class="string">$P"</span><span class="plain">, </span><span class="identifier">referent</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="reserved">return</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_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_5"></a><b>&#167;9.7.5. </b>For example, "above" and "below" become significant if the mapping plugin
is active, and "nowhere" if the spatial one is.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on any special noun phrases significant to plugins</span> <span class="cwebmacronumber">9.7.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Plugins::Call::act_on_special_NPs</span><span class="plain">(</span><span class="identifier">p</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_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_6"></a><b>&#167;9.7.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Interpret this as an existing noun if possible</span> <span class="cwebmacronumber">9.7.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Parse the noun phrase as a value property name</span> <span class="cwebmacronumber">9.7.6.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Parse the noun phrase as a value</span> <span class="cwebmacronumber">9.7.6.3</span>&gt;<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="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="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">p</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="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>
&lt;<span class="cwebmacro">Act on a description used as a noun phrase</span> <span class="cwebmacronumber">9.7.6.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on an action pattern used as a noun phrase</span> <span class="cwebmacronumber">9.7.6.4</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_6_1"></a><b>&#167;9.7.6.1. </b>Perhaps it is the name of a valued property? If so, it is used as a noun,
without obvious reference to any owner: we convert it to a noun node.
</p>
<p class="inwebparagraph">(This is the next priority so that "description" will be read as its
property name meaning, not as the name of a kind of value.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse the noun phrase as a value property name</span> <span class="cwebmacronumber">9.7.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">value</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)))</span>
<span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_property</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7_6">&#167;9.7.6</a>.</p>
<p class="inwebparagraph"><a id="SP_1"></a><b>&#167;.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_VagueVariable problem</span> <span class="cwebmacronumber">.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">FALSE</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_VagueVariable</span><span class="plain">),</span>
<span class="string">"'variable' is too vague a description"</span><span class="plain">,</span>
<span class="string">"because it doesn't say what kind of value should go into the variable. "</span>
<span class="string">"'number variable' or 'a number that varies' - whatever kind of value you "</span>
<span class="string">"need - would be much clearer."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7_6_2">&#167;9.7.6.2</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_6_2"></a><b>&#167;9.7.6.2. </b>When a noun phrase in an assertion represents a value, it's normally a
constant ("13") or else something like a description of values ("a number").
It wouldn't make sense to refer to a temporary value like a local variable,
but a global ("player" or "time of day") is possible.
</p>
<p class="inwebparagraph">The "action of taking something" syntax is provided as a way of escaping
the usual handling of action patterns; it enables "taking something" to be
a noun instead of a condition testing the current action.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">assertion</span><span class="plain">-</span><span class="identifier">np</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt; ::=</span>
<span class="identifier">variable</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_VagueVariable problem</span> <span class="cwebmacronumber">.1</span>&gt;
<span class="identifier">action</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">explicit</span><span class="plain">-</span><span class="identifier">action</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">descriptive</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">global</span><span class="plain">-</span><span class="identifier">variable</span><span class="plain">&gt; ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9_7_6_3"></a><b>&#167;9.7.6.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse the noun phrase as a value</span> <span class="cwebmacronumber">9.7.6.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">assertion</span><span class="plain">-</span><span class="identifier">np</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Descriptions::get_quantifier</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Check that this noun phrase is allowed a quantifier</span> <span class="cwebmacronumber">9.7.6.3.1</span>&gt;<span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">NOUN_RESOLUTION</span><span class="plain">, </span><span class="string">"Noun phrase %W parsed as value: $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">), </span><span class="identifier">spec</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7_6">&#167;9.7.6</a>.</p>
<p class="inwebparagraph"><a id="SP_1"></a><b>&#167;.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for a variable described without a kind</span> <span class="cwebmacronumber">.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is never used.</p>
<p class="inwebparagraph"><a id="SP9_7_6_3_1"></a><b>&#167;9.7.6.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that this noun phrase is allowed a quantifier</span> <span class="cwebmacronumber">9.7.6.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Quantifiers::can_be_used_in_assertions</span><span class="plain">(</span><span class="functiontext">Descriptions::get_quantifier</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T\</span><span class="plain">n</span><span class="string">So $D\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">spec</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_ComplexDeterminer</span><span class="plain">),</span>
<span class="string">"complicated determiners are not allowed in assertions"</span><span class="plain">,</span>
<span class="string">"so for instance 'More than three people are in the Dining Room' "</span>
<span class="string">"or 'None of the containers is open' will be rejected. Only "</span>
<span class="string">"simple numbers will be allowed, as in examples like 'Three "</span>
<span class="string">"people are in the Dining Room.'"</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="functiontext">Descriptions::get_quantifier</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="identifier">for_all_quantifier</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">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K</span><span class="plain">) &amp;&amp;</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="identifier">NULL</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Descriptions::number_of_adjectives_applied_to</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == 0)) {</span>
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">p</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">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">EVERY_NT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</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_ComplexEvery</span><span class="plain">),</span>
<span class="string">"in an assertion 'every' or 'all' can only be used with a kind"</span><span class="plain">,</span>
<span class="string">"so for instance 'A coin is in every container' is all right, "</span>
<span class="string">"because 'container' is a kind, but not 'A coin is in every "</span>
<span class="string">"open container', because 'open container' is now a kind "</span>
<span class="string">"qualified by a property which may come or go during play. "</span>
<span class="string">"(This problem sometimes happens because a thing has been "</span>
<span class="string">"called something like an 'all in one survival kit' - if you "</span>
<span class="string">"need that sort of name, try using 'called' to set it.)"</span><span class="plain">);</span>
<span class="reserved">return</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_7_6_3">&#167;9.7.6.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_6_4"></a><b>&#167;9.7.6.4. </b>If the noun phrase is a valid action pattern, such as "taking something",
we change it to a new node type to mark this. We don't keep the pattern:
it will be reparsed much later on.
</p>
<p class="inwebparagraph">We have to be a little cautious, because of the way English allows participles
as nouns to mean the result of some action having taken place on something &mdash;
consider "the scoring", for instance, in the sense of a mark scored on a
piece of wood. So we parse action patterns with a lower priority than values
here, given that we know we are looking for a noun.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on an action pattern used as a noun phrase</span> <span class="cwebmacronumber">9.7.6.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">nounphrase_article_ANNOT</span><span class="plain">) == </span><span class="identifier">NO_ART</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">pattern</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) {</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">ACTION_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_action_meaning</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</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_7_6">&#167;9.7.6</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_6_5"></a><b>&#167;9.7.6.5. </b>This case has been left to last, since it's so much the most difficult.
Descriptions have to be converted into a surprising range of different
subtrees &mdash; otherwise it will not be possible to issue a wide range of
to-the-point problem messages for badly constructed sentences.
</p>
<p class="inwebparagraph">Oddly, it's not the complicated descriptions which give trouble...
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on a description used as a noun phrase</span> <span class="cwebmacronumber">9.7.6.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">p</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="functiontext">Descriptions::is_complex</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">p</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="plain">}</span>
&lt;<span class="cwebmacro">Act on a simple description</span> <span class="cwebmacronumber">9.7.6.5.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7_6">&#167;9.7.6</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_6_5_1"></a><b>&#167;9.7.6.5.1. </b>...it's the shorter phrases where, perversely, the risk of a
misunderstanding is higher. For one thing, we deliberately ignore a valid
description in two cases:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Adjective(s) followed by the name of a specific object.
</li><li>(b) An indefinite article followed by the name of a specific object.
</li></ul>
<p class="inwebparagraph">For (a), see the example "Goat-Cheese and Sage Chicken". This contains a
kettle which can be in several states, described adjectivally, and one of
those is "heating". This means the S-parser reads "heating kettle" as if it
meant "the kettle when in the heating state". But we don't want this to be
recognised in an assertion, because it's not useful to talk about individual
objects in particular states when setting up the initial state &mdash; the kettle
either starts out as heating, or it doesn't. Moreover, we don't want to
misread a line like:
</p>
<blockquote>
<p>Heating Kettle is a scene.</p>
</blockquote>
<p class="inwebparagraph">(also a sentence from "Goat-Cheese and Sage Chicken"). Because of this and
similar ambiguities, we ignore the S-parser's recommendation of reading
adjective(s) plus proper noun as a reference to that noun in a special state.
</p>
<p class="inwebparagraph">Case (b) comes out of a point of difference between proper and common nouns:
use of an indefinite article is fine with common nouns &mdash; "a container", for
example &mdash; but not with proper nouns: talking about "a silver bar" suggests
that this is not the same silver bar referred to in some previous
sentence.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on a simple description</span> <span class="cwebmacronumber">9.7.6.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">)) &amp;&amp;</span>
<span class="plain">((</span><span class="functiontext">Descriptions::number_of_adjectives_applied_to</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) &gt; 0) ||</span>
<span class="plain">(</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">nounphrase_article_ANNOT</span><span class="plain">) != </span><span class="identifier">DEF_ART</span><span class="plain">)))) {</span>
<span class="functiontext">Assertions::Refiner::refine_from_simple_description</span><span class="plain">(</span><span class="identifier">p</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7_6_5">&#167;9.7.6.5</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>The following turns the node <code class="display"><span class="extract">p</span></code> into a subtree representing the content of
a simple description in <code class="display"><span class="extract">spec</span></code>. Besides being used above, it's also convenient
for assemblies.
</p>
<p class="inwebparagraph">Depending on the circumstances, we get a subtree in which the headword if any
is represented by an <code class="display"><span class="extract">COMMON_NOUN_NT</span></code> node (where the headword is a kind of
object) or a <code class="display"><span class="extract">PROPER_NOUN_NT</span></code> (where the headword is a specific object), and
where the adjectives each become <code class="display"><span class="extract">ADJECTIVE_NT</span></code> nodes.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::refine_from_simple_description</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</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="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">head</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Set the attachment node to the headword, if there is one</span> <span class="cwebmacronumber">10.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Descriptions::number_of_adjectives_applied_to</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">head</span><span class="plain">) </span>&lt;<span class="cwebmacro">Insert a WITH node joining adjective tree to headword</span> <span class="cwebmacronumber">10.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Place a subtree of adjectives at the attachment node</span> <span class="cwebmacronumber">10.3</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::refine_from_simple_description is used in <a href="#SP9_7_6_5_1">&#167;9.7.6.5.1</a>, 9/ass (<a href="9-ass.html#SP9_3">&#167;9.3</a>).</p>
<p class="inwebparagraph"><a id="SP10_1"></a><b>&#167;10.1. </b>Crucially, the headword node gets one extra annotation: its "full phrase
evaluation", which retains the original description information &mdash; in
particular, quantification data such as that in "four doors", which
would be lost if we simply applied <code class="display"><span class="extract">Assertions::Refiner::noun_from_infs</span></code> to the inference
subject for "door".
</p>
<p class="inwebparagraph">If <code class="display"><span class="extract">head</span></code> is not set, it doesn't matter what we do, because there'll be
no headword node &mdash; this is why we don't bother to find any subject to
set for it.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Set the attachment node to the headword, if there is one</span> <span class="cwebmacronumber">10.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<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="identifier">head</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="identifier">head</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">head</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::pn_noun_details_from_spec</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</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="functiontext">Descriptions::makes_kind_explicit</span><span class="plain">(</span><span class="identifier">spec</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">spec</span><span class="plain">);</span>
<span class="identifier">head</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="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">head</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_evaluation</span><span class="plain">(</span><span class="identifier">p</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="functiontext">Assertions::Refiner::pn_noun_details_from_spec</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP10_2"></a><b>&#167;10.2. </b>We put a WITH node in the attachment position, displacing the headword
content to its first child, and making its second child the new attachment
position &mdash; so that that is where the adjectives subtree will go.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Insert a WITH node joining adjective tree to headword</span> <span class="cwebmacronumber">10.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">lower_copy</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::copy</span><span class="plain">(</span><span class="identifier">lower_copy</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">WITH_NT</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">lower_copy</span><span class="plain">;</span>
<span class="identifier">lower_copy</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="identifier">lower_copy</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP10_3"></a><b>&#167;10.3. </b>When there are two or more adjectives, they must occur as leaves of a
binary tree whose non-leaf nodes are <code class="display"><span class="extract">AND_NT</span></code>. We do this pretty inefficiently,
making no effort to balance the tree, since it has negligible effect on speed
or memory.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Place a subtree of adjectives at the attachment node</span> <span class="cwebmacronumber">10.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_adjectives</span><span class="plain"> = </span><span class="functiontext">Descriptions::number_of_adjectives_applied_to</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">no_adjectives</span><span class="plain"> == 1) {</span>
<span class="functiontext">Assertions::Refiner::pn_make_adjective</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">,</span>
<span class="functiontext">Descriptions::first_adjective_usage</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">), </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">ParseTree::set_type_and_clear_annotations</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">AND_NT</span><span class="plain">);</span>
<span class="identifier">adjective_usage</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">i</span><span class="plain"> = 0;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">AND_p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">ale_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_ADJECTIVE_LIST</span><span class="plain">(</span><span class="identifier">ale</span><span class="plain">, </span><span class="identifier">ale_prop</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain">++;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p3</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">ADJECTIVE_NT</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::pn_make_adjective</span><span class="plain">(</span><span class="identifier">p3</span><span class="plain">, </span><span class="identifier">ale</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">i</span><span class="plain"> &lt; </span><span class="identifier">no_adjectives</span><span class="plain">) {</span>
<span class="identifier">AND_p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">p3</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">+1 &lt; </span><span class="identifier">no_adjectives</span><span class="plain">) {</span>
<span class="identifier">p3</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">AND_NT</span><span class="plain">);</span>
<span class="identifier">AND_p</span><span class="plain"> = </span><span class="identifier">p3</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">AND_p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">p3</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">This code is used in <a href="#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. About surgeries. </b>The rest of this section is taken up with four local surgical operations
performed on the tree in the light of what we can now see. In each case, the
problem is that two clausal constructions implied by the nodes inserted
earlier have been applied the wrong way round:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(1) "And surgery": <code class="display"><span class="extract">AND_NT</span></code> and <code class="display"><span class="extract">WITH_NT</span></code> the wrong way round.
</li></ul>
<ul class="items"><li>(2) "With surgery": <code class="display"><span class="extract">WITH_NT</span></code> and <code class="display"><span class="extract">WITH_NT</span></code> where just one will do, though
in disguised form this is another clash with <code class="display"><span class="extract">AND_NT</span></code>.
</li></ul>
<ul class="items"><li>(3) "Location surgery": <code class="display"><span class="extract">AND_NT</span></code> and <code class="display"><span class="extract">RELATIONSHIP_NT</span></code> the wrong way round.
</li></ul>
<ul class="items"><li>(4) "Called surgery": <code class="display"><span class="extract">CALLED_NT</span></code> and <code class="display"><span class="extract">RELATIONSHIP_NT</span></code> the wrong way round.
</li></ul>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. And surgery. </b>"And surgery" is a fiddly operation to correct the parse tree after
resolution of all the nouns in a phrase which involves both "and" and
"with" in a particular way. There's no problem with either of these:
</p>
<blockquote>
<p>In the Pitch are a bat and ball with score for finding 10. In the Pitch is a sweater with score for finding 5 and description "White wool."</p>
</blockquote>
<p class="inwebparagraph">neither of which is altered by and surgery. The difficulty arises with
</p>
<blockquote>
<p>In the Pitch is an openable and open door with description "The Hut door."</p>
</blockquote>
<p class="inwebparagraph">which, we notice, has exactly the same grammatical structure as the first of
the two sentences above, yet a very different meaning, since "openable" is a
property whereas "bat" was an object. We perform surgery on:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">AND_NT</span>
<span class="plain"> ADJECTIVE_NT prop:p46_openable</span>
<span class="plain"> WITH_NT</span>
<span class="plain"> COMMON_NOUN_NT K4_door</span>
<span class="plain"> ADJECTIVE_NT prop:p44_open</span>
</pre>
<p class="inwebparagraph">to restructure the nodes as:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">WITH_NT</span>
<span class="plain"> COMMON_NOUN_NT K4_door</span>
<span class="plain"> AND_NT</span>
<span class="plain"> ADJECTIVE_NT prop:p46_openable</span>
<span class="plain"> ADJECTIVE_NT prop:p44_open</span>
</pre>
<p class="inwebparagraph">This innocent-looking little routine involved drawing a lot of diagrams
on the back of an envelope. Change at your peril.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::perform_and_surgery</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">x</span><span class="plain">, *</span><span class="identifier">a_p</span><span class="plain">, *</span><span class="identifier">w_p</span><span class="plain">, *</span><span class="identifier">p1_p</span><span class="plain">, *</span><span class="identifier">p2_p</span><span class="plain">, *</span><span class="identifier">i_p</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) == </span><span class="constant">ADJECTIVE_NT</span><span class="plain">)</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">)) {</span>
<span class="identifier">a_p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="identifier">p1_p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">; </span><span class="identifier">w_p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="identifier">i_p</span><span class="plain"> = </span><span class="identifier">w_p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">; </span><span class="identifier">p2_p</span><span class="plain"> = </span><span class="identifier">i_p</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">a_p</span><span class="plain">, </span><span class="identifier">WITH_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_type_and_clear_annotations</span><span class="plain">(</span><span class="identifier">w_p</span><span class="plain">, </span><span class="identifier">AND_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">a_p</span><span class="plain">, </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">w_p</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">w_p</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">a_p</span><span class="plain">; </span><span class="identifier">a_p</span><span class="plain"> = </span><span class="identifier">w_p</span><span class="plain">; </span><span class="identifier">w_p</span><span class="plain"> = </span><span class="identifier">x</span><span class="plain">;</span>
<span class="identifier">w_p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">i_p</span><span class="plain">;</span>
<span class="identifier">i_p</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">a_p</span><span class="plain">;</span>
<span class="identifier">a_p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">p1_p</span><span class="plain">;</span>
<span class="identifier">a_p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">p2_p</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::perform_and_surgery is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. With surgery. </b>This is a less traumatic operation, motivated by sentences like:
</p>
<blockquote>
<p>In the Pitch is an open container with description "The box of stumps and bails."</p>
</blockquote>
<p class="inwebparagraph">The initial parse tree for such a sentence will have two nested <code class="display"><span class="extract">WITH_NT</span></code>
clauses, which is arguably correct &mdash; "a (container with property open)
with description ..." &mdash; but which is inconvenient for our implementation
of <code class="display"><span class="extract">WITH_NT</span></code> later on. So we construe the sentence instead with a single
"with", as "a container with properties open and description ..." In
terms of the tree,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">WITH_NT</span>
<span class="plain"> WITH_NT</span>
<span class="plain"> COMMON_NOUN_NT K4_container</span>
<span class="plain"> ADJECTIVE_NT prop:p44_open</span>
<span class="plain"> PROPERTY_LIST_NT "The box..."</span>
</pre>
<p class="inwebparagraph">is reconstructed as:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">WITH_NT</span>
<span class="plain"> COMMON_NOUN_NT K4_container</span>
<span class="plain"> AND_NT</span>
<span class="plain"> ADJECTIVE_NT prop:p44_open</span>
<span class="plain"> PROPERTY_LIST_NT "The box..."</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::perform_with_surgery</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inst</span><span class="plain">, *</span><span class="identifier">prop_1</span><span class="plain">, *</span><span class="identifier">prop_2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">)) {</span>
<span class="identifier">inst</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="identifier">prop_1</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="identifier">prop_2</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">inst</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">AND_NT</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">prop_1</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">prop_2</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::perform_with_surgery is used in <a href="#SP9_2">&#167;9.2</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Location surgery. </b>This is needed to make sentences like the second one
here work:
</p>
<blockquote>
<p>The escalator is a door. It is below the Kudamm and above the U-Bahn.</p>
</blockquote>
<pre class="display">
<span class="plain"> RELATIONSHIP_NT &lt;below&gt; (CONTAINS_THINGS_INF)</span>
<span class="plain"> AND_NT</span>
<span class="plain"> PROPER_NOUN_NT &lt;kudamm&gt; (definite)</span>
<span class="plain"> RELATIONSHIP_NT &lt;above&gt; (CONTAINS_THINGS_INF)</span>
<span class="plain"> PROPER_NOUN_NT &lt;u-bahn&gt; (definite)</span>
</pre>
<p class="inwebparagraph">into:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain"> AND_NT</span>
<span class="plain"> RELATIONSHIP_NT &lt;below&gt; (CONTAINS_THINGS_INF)</span>
<span class="plain"> PROPER_NOUN_NT &lt;kudamm&gt; (definite)</span>
<span class="plain"> RELATIONSHIP_NT &lt;above&gt; (CONTAINS_THINGS_INF)</span>
<span class="plain"> PROPER_NOUN_NT &lt;u-bahn&gt; (definite)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::perform_location_surgery</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">old_and</span><span class="plain">, *</span><span class="identifier">old_np1</span><span class="plain">, *</span><span class="identifier">old_loc2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">RELATIONSHIP_NT</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) == </span><span class="identifier">AND_NT</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) == </span><span class="identifier">RELATIONSHIP_NT</span><span class="plain">)) {</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">resolved_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">); </span> <span class="comment">otherwise this will be wrongly copied</span>
<span class="identifier">old_and</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="identifier">old_np1</span><span class="plain"> = </span><span class="identifier">old_and</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="identifier">old_loc2</span><span class="plain"> = </span><span class="identifier">old_and</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="identifier">ParseTree::copy</span><span class="plain">(</span><span class="identifier">old_and</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">); </span> <span class="comment">making this the new first location node</span>
<span class="identifier">ParseTree::set_type_and_clear_annotations</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">AND_NT</span><span class="plain">); </span> <span class="comment">and this is new AND</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">old_and</span><span class="plain">;</span>
<span class="identifier">old_and</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">old_np1</span><span class="plain">;</span>
<span class="identifier">old_and</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">old_loc2</span><span class="plain">;</span>
<span class="identifier">old_np1</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::perform_location_surgery is used in <a href="#SP9_5">&#167;9.5</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Called surgery. </b>The following case occurs very rarely, on a noun phrase such as
"north of a room called the Hot and Cold Room". The problem, as usual, is
the two clauses are the wrong way around, so we perform surgery to turn:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">CALLED_NT &lt;called&gt;</span>
<span class="plain"> RELATIONSHIP_NT &lt;north of a room&gt; (type:direction)</span>
</pre>
<p class="inwebparagraph"> <code class="display"><span class="extract"> PROPER_NOUN_NT &lt;room&gt; (indefinite)</span></code>
</p>
<pre class="display">
<span class="plain"> PROPER_NOUN_NT &lt;north&gt; (no article)</span>
<span class="plain"> PROPER_NOUN_NT &lt;hot and cold room&gt; (definite)</span>
</pre>
<p class="inwebparagraph">into:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">RELATIONSHIP_NT &lt;called&gt; (type:direction)</span>
<span class="plain"> CALLED_NT &lt;north of a room&gt;</span>
</pre>
<p class="inwebparagraph"> <code class="display"><span class="extract"> COMMON_NOUN_NT &lt;room&gt;</span></code>
<code class="display"><span class="extract"> CREATED_NT &lt;hot and cold room&gt;</span></code>
<code class="display"><span class="extract"> PROPER_NOUN_NT &lt;north&gt; (no article)</span></code>
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::perform_called_surgery</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">x_pn</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">; </span> <span class="comment">"north" in the example</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">name_pn</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">; </span> <span class="comment">"hot and cold room" in the example</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">RELATIONSHIP_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">relationship_node_type_ANNOT</span><span class="plain">,</span>
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">relationship_node_type_ANNOT</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">CALLED_NT</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">x_pn</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">name_pn</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::perform_called_surgery is used in <a href="#SP9_4">&#167;9.4</a>.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. The player is not yourself. </b>The following routine handles a feature added to Inform to handle just one
peculiarity of syntax: that the source text will often talk about "the
player" to mean the object which represents the player at the start of
play (properly called "yourself"), not the variable whose value is the
object currently representing the player.
</p>
<p class="inwebparagraph">But no explicit mention of this case appears here; in theory any plugin
can set up aliases of variable names to constants like this.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Assertions::Refiner::turn_player_to_yourself</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">) == </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">, </span><span class="constant">turned_already_ANNOT</span><span class="plain">) == </span><span class="identifier">FALSE</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::parse</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</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">q</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="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">diversion</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">, </span><span class="constant">turned_already_ANNOT</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">TRUE</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">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Refiner::turn_player_to_yourself 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_20">&#167;3.3.20</a>, <a href="9-ma.html#SP3_3_25">&#167;3.3.25</a>, <a href="9-ma.html#SP3_3_26">&#167;3.3.26</a>, <a href="9-ma.html#SP3_3_29">&#167;3.3.29</a>, <a href="9-ma.html#SP3_3_36">&#167;3.3.36</a>, <a href="9-ma.html#SP3_3_37">&#167;3.3.37</a>), 9/rk (<a href="9-rk.html#SP3_1">&#167;3.1</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="9-tbath.html">Back to 'To Be and To Have'</a></li><li><a href="9-tc.html">Continue with 'The Creator'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>