1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/9-pd.html
2019-04-22 15:42:10 +01:00

1048 lines
106 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>9/imp</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/pd' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#9">Chapter 9: The A-Parser</a></li><li><b>Property Declarations</b></li></ul><p class="purpose">To parse sentences which create new properties, or assert that particular kinds of value can possess them.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. X can be Y or Z</a></li><li><a href="#SP6">&#167;6. X has a K called P</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. X can be Y or Z. </b>Just one ingredient of assertion-parsing is missing: the handling of sentences
which create and assign properties.
</p>
<p class="inwebparagraph">First we handle the special meaning of "to be either", as in "X is either
Y or Z...".
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">either</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ::=</span>
<span class="identifier">either</span><span class="plain"> &lt;</span><span class="identifier">nounphrase</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="SP2"></a><b>&#167;2. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Assertions::Property::either_SMF</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">NPs</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[0]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">OW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[1]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">task</span><span class="plain">) { </span> <span class="comment">"A room is either dark or lighted."</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ACCEPT_SMFT</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">either</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">OW</span><span class="plain">)) {</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">, </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">O</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">&gt;(</span><span class="identifier">SW</span><span class="plain">);</span>
<span class="identifier">V</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">V</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">O</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1:</span>
<span class="functiontext">Assertions::Property::declare_property_can_be</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">break</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::Property::either_SMF is used in 6/nv (<a href="6-nv.html#SP16">&#167;16</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Assertions::Property::optional_either_SMF</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">NPs</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[0]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">OW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[1]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">task</span><span class="plain">) { </span> <span class="comment">"A room can be dark or lighted."</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ACCEPT_SMFT</span><span class="plain">:</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">, </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">);</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt;(</span><span class="identifier">OW</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">O</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">&gt;(</span><span class="identifier">SW</span><span class="plain">);</span>
<span class="identifier">V</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">V</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">O</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="reserved">case</span><span class="plain"> </span><span class="constant">TRAVERSE1_SMFT</span><span class="plain">:</span>
<span class="functiontext">Assertions::Property::declare_property_can_be</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">break</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::Property::optional_either_SMF is used in 6/nv (<a href="6-nv.html#SP16">&#167;16</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>From a syntax point of view, such sentences come in two forms &mdash; those which
give a range of possible named alternative states, and those which create
named value properties. We'll take the first of those first.
</p>
<p class="inwebparagraph">We are concerned here with the syntax of sentences like
</p>
<blockquote>
<p>A container can be stout, standard or fragile (this is its strength property).</p>
</blockquote>
<p class="inwebparagraph">The subject (in this example, "a container") is required not to match:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">forbidden</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">owners</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">article</span><span class="plain">&gt; </span><span class="identifier">kind</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_PropertyOfKind1 problem</span> <span class="cwebmacronumber">4.1</span>&gt;
<span class="identifier">kind</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_PropertyOfKind1 problem</span> <span class="cwebmacronumber">4.1</span>&gt;
<span class="plain">&lt;</span><span class="identifier">pronoun</span><span class="plain">&gt; ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_PropertyOfPronoun problem</span> <span class="cwebmacronumber">4.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_PropertyOfKind1 problem</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = -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_PropertyOfKind1</span><span class="plain">),</span>
<span class="string">"this seems to give a property to all kinds, rather than to objects or "</span>
<span class="string">"values"</span><span class="plain">,</span>
<span class="string">"which are the only things capable of having properties. For instance, "</span>
<span class="string">"'A vehicle has a number called maximum speed' is fine, but not 'A kind "</span>
<span class="string">"has a number called coolness rating'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a> (twice).</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_PropertyOfPronoun problem</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = -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_PropertyOfPronoun</span><span class="plain">),</span>
<span class="string">"it's often a little ambiguous to declare properties for 'it'"</span><span class="plain">,</span>
<span class="string">"so it seems best to spell this out by saying exactly what the "</span>
<span class="string">"property's owner or owners would be."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>It might look as if this should always create an either/or property, and
in the speedy/sluggish example that's just what it does, but if there are
three or more alternatives then it has to do something trickier: create a
value property, and a new kind of value of which these alternatives form
the legal range. Such a property is customarily called a "condition" (in
the sense of a state of something, not a test &mdash; as in "this antique is in
good condition", not "you can come in on one condition").
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Property::declare_property_can_be</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">the_owner</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">the_list</span><span class="plain"> = </span><span class="identifier">the_owner</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">can</span><span class="plain">-</span><span class="identifier">be</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_list</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">either_flag</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">the_list</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="identifier">the_list</span><span class="plain"> = </span><span class="identifier">the_list</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CNW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">the_list</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) </span><span class="identifier">CNW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_list</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">the_owner</span><span class="plain">, </span><span class="constant">FORBID_CREATION</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Possession must be time-independent</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">count</span><span class="plain"> = </span><span class="functiontext">Assertions::Property::list_length</span><span class="plain">(</span><span class="identifier">the_list</span><span class="plain">);</span>
&lt;<span class="cwebmacro">An optional condition name can only be given to a condition</span> <span class="cwebmacronumber">5.3</span>&gt;<span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">FW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> == 1) </span><span class="identifier">FW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_list</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">FW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_list</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Allow the word "either" as syntactic sugar when there are two alternatives</span> <span class="cwebmacronumber">5.5</span>&gt;<span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> &gt;= 2) </span><span class="identifier">SW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_list</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"> (&lt;</span><span class="identifier">forbidden</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">owners</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_owner</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">owner_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Determine the proud owner, and see if it's someone we consider worthy</span> <span class="cwebmacronumber">5.6</span>&gt;<span class="character">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner_infs</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem message for an unworthy owner</span> <span class="cwebmacronumber">5.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> &lt;= 2) </span>&lt;<span class="cwebmacro">Be very wary about nameclashes among either/or properties like these</span> <span class="cwebmacronumber">5.8</span>&gt;<span class="plain">;</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">already_created_instances</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Create the property and have the new owner provide it</span> <span class="cwebmacronumber">5.9</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">already_created_instances</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> == 2) </span>&lt;<span class="cwebmacro">Make the second option an either/or property which negates the first</span> <span class="cwebmacronumber">5.10</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> &gt;= 3) </span>&lt;<span class="cwebmacro">Make the three or more options the range of possibilities for this new kind</span> <span class="cwebmacronumber">5.11</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::Property::declare_property_can_be is used in <a href="#SP2">&#167;2</a>, <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Assertions::Property::list_length</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">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">"Ooops"</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>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Assertions::Property::list_length</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::Property::list_length</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">return</span><span class="plain"> 1;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Property::list_length is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b>And the following parses the object noun phrase of a "can be" sentence,
which might take forms such as:
</p>
<blockquote>
<p>either speedy or sluggish</p>
</blockquote>
<blockquote>
<p>fast or slow</p>
</blockquote>
<blockquote>
<p>allegro, presto, or adagio (the speed property)</p>
</blockquote>
<blockquote>
<p>allegro, presto, or adagio (this is its speed property)</p>
</blockquote>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">can</span><span class="plain">-</span><span class="identifier">be</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ::=</span>
<span class="identifier">either</span><span class="plain"> &lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">alternative</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ( &lt;</span><span class="identifier">condition</span><span class="plain">-</span><span class="identifier">name</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="identifier">parse_node</span><span class="plain"> *) </span><span class="identifier">RP</span><span class="plain">[1])-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2];</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">alternative</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ( &lt;</span><span class="identifier">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ) | ==&gt; </span><span class="identifier">FALSE</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="identifier">parse_node</span><span class="plain"> *) </span><span class="identifier">RP</span><span class="plain">[1])-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2];</span>
<span class="identifier">either</span><span class="plain"> &lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">alternative</span><span class="plain">-</span><span class="identifier">list</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">nounphrase</span><span class="plain">-</span><span class="identifier">alternative</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ==&gt; </span><span class="identifier">FALSE</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">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ::=</span>
<span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> &lt;</span><span class="identifier">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; | ==&gt; 0; *</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">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; ==&gt; 0; *</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">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">innermost</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">possessive</span><span class="plain">-</span><span class="identifier">third</span><span class="plain">-</span><span class="identifier">person</span><span class="plain">&gt; &lt;</span><span class="identifier">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">innermost</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">innermost</span><span class="plain">&gt; ==&gt; 0; *</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">condition</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">innermost</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt; </span><span class="reserved">property</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>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt; ==&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="SP5_3"></a><b>&#167;5.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">An optional condition name can only be given to a condition</span> <span class="cwebmacronumber">5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">CNW</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">count</span><span class="plain"> &lt; 3)) {</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_ThisIsEitherOr</span><span class="plain">),</span>
<span class="string">"a name can only be supplied using '... (this is...)' when a new property "</span>
<span class="string">"is being made with three or more named alternatives"</span><span class="plain">,</span>
<span class="string">"whereas here a simpler either/or property is being made with just one or "</span>
<span class="string">"two possibilities - which means these named outcomes are the property names "</span>
<span class="string">"themselves. For instance, 'A book can be mint or foxed' makes two either/or "</span>
<span class="string">"properties, one called 'mint', the other called 'foxed'. So 'A book can "</span>
<span class="string">"be mint or foxed (this is the cover state)' is not allowed."</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="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_4"></a><b>&#167;5.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Possession must be time-independent</span> <span class="cwebmacronumber">5.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">the_owner</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_QualifiedCanBe</span><span class="plain">),</span>
<span class="string">"only a room, a thing or a kind can have such adjectives applied to it"</span><span class="plain">,</span>
<span class="string">"and qualifications cannot be used. It makes no sense to say 'An open door "</span>
<span class="string">"can be rickety or sturdy' because the door still has to have the property "</span>
<span class="string">"even at times when it is not open: we must instead just say 'A door can be "</span>
<span class="string">"rickety or sturdy'."</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="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_5"></a><b>&#167;5.5. </b>This allows for natural sentences such as:
</p>
<blockquote>
<p>An animal can be either alive or dead.</p>
</blockquote>
<p class="inwebparagraph">Here "either" has a slight sense of emphasis, implying the exclusivity of the
two choices &mdash; the lack of a middle way. That's not useful information for us,
because to Inform all either/or properties have that Aristotelian nature. But
we found in testing that users wrote the word "either" now and then,
regardless of what the documentation said. So we'll allow it but do nothing
differently as a result.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Allow the word "either" as syntactic sugar when there are two alternatives</span> <span class="cwebmacronumber">5.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">either_flag</span><span class="plain">) &amp;&amp; (</span><span class="identifier">count</span><span class="plain"> != 2)) {</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_EitherOnThree</span><span class="plain">),</span>
<span class="string">"that looks like an attempt to use 'either' other than to lay out exactly "</span>
<span class="string">"two possibilities"</span><span class="plain">,</span>
<span class="string">"which is not allowed. (Technically it ought to be legal to have a property "</span>
<span class="string">"whose name actually starts with 'either' but the confusion would be just "</span>
<span class="string">"too awful to contemplate.)"</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="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_6"></a><b>&#167;5.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Determine the proud owner, and see if it's someone we consider worthy</span> <span class="cwebmacronumber">5.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner_spec</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">the_owner</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::is_actual_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">owner_spec</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Disallow this variable as a new owner of a property</span> <span class="cwebmacronumber">5.6.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Descriptions::is_qualified</span><span class="plain">(</span><span class="identifier">owner_spec</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Disallow this as an owner not time-independent</span> <span class="cwebmacronumber">5.6.3</span>&gt;<span class="plain">;</span>
<span class="identifier">owner_infs</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">the_owner</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner_infs</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">owner_spec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_owner</span><span class="plain">)))</span>
<span class="identifier">owner_infs</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;));</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">owner_infs</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="identifier">Kinds::Behaviour::has_properties</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Disallow this kind as a new owner of an either/or or condition</span> <span class="cwebmacronumber">5.6.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_6_1"></a><b>&#167;5.6.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Disallow this kind as a new owner of an either/or or condition</span> <span class="cwebmacronumber">5.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ValueCantHaveProperties</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 looked to me as if it might be trying to create an either/or "</span>
<span class="string">"property which would be held by all of the values of a rather large kind "</span>
<span class="string">"(%2). But this is a kind which is not allowed to have properties, because "</span>
<span class="string">"the storage requirements would be too difficult. For instance, scenes can "</span>
<span class="string">"have properties like this, but numbers can't: that's because there are only "</span>
<span class="string">"a few, named scenes, but there is an almost unlimited range of numbers. (That "</span>
<span class="string">"doesn't mean you can't create adjectives using 'Definition: ...' - it's "</span>
<span class="string">"only when storage would be needed that this limitation kicks in.)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_6">&#167;5.6</a>.</p>
<p class="inwebparagraph"><a id="SP5_6_2"></a><b>&#167;5.6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Disallow this variable as a new owner of a property</span> <span class="cwebmacronumber">5.6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">the_owner</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_VariableCantHaveProperties</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 looked to me as if it might be trying to create an either/or "</span>
<span class="string">"property which would be held by a variable ('%2'). But because '%2' can have "</span>
<span class="string">"different values at different times, it's not clear who or what should have "</span>
<span class="string">"the property. "</span>
<span class="string">"%PThe most common case of this is saying something like 'The player can "</span>
<span class="string">"be ambitious'. 'The player' is actually a variable, because the perspective "</span>
<span class="string">"of play can change. Instead either say 'A person can be ambitious' or, if "</span>
<span class="string">"you really only want the default player to be involved, 'Yourself can be "</span>
<span class="string">"ambitious'."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_6">&#167;5.6</a>.</p>
<p class="inwebparagraph"><a id="SP5_6_3"></a><b>&#167;5.6.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Disallow this as an owner not time-independent</span> <span class="cwebmacronumber">5.6.3</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_OwnerTimeDependent</span><span class="plain">),</span>
<span class="string">"ownership of a property is something that has to be always true or "</span>
<span class="string">"always false"</span><span class="plain">,</span>
<span class="string">"so that 'a room can be secret' is fine - a room is always a room - "</span>
<span class="string">"but 'a dark room can be secret' is not - a room might be dark some "</span>
<span class="string">"of the time, and lighted the rest of the time. You need to give a "</span>
<span class="string">"straightforward owner, and not qualify it with adjectives or "</span>
<span class="string">"other conditions."</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="#SP5_6">&#167;5.6</a>.</p>
<p class="inwebparagraph"><a id="SP5_7"></a><b>&#167;5.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for an unworthy owner</span> <span class="cwebmacronumber">5.7</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_NonObjectCanBe</span><span class="plain">),</span>
<span class="string">"only a room, a thing or a kind can have such adjectives applied to it"</span><span class="plain">,</span>
<span class="string">"so that 'a dead end can be secret' is fine but 'taking can be secret' would "</span>
<span class="string">"not be, since 'taking' is an action and not a room, thing or kind."</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="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_8"></a><b>&#167;5.8. </b>There are seven different ways this can go wrong, and they all share a
"miscellaneous" problem message.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Be very wary about nameclashes among either/or properties like these</span> <span class="cwebmacronumber">5.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">error_text</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">EW</span><span class="plain"> = </span><span class="identifier">FW</span><span class="plain">;</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">already</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">FW</span><span class="plain">)) </span><span class="identifier">already</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
&lt;<span class="cwebmacro">See if the first option already means something incompatible with this</span> <span class="cwebmacronumber">5.8.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">count</span><span class="plain"> == 2) &amp;&amp; (</span><span class="identifier">error_text</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">EW</span><span class="plain"> = </span><span class="identifier">SW</span><span class="plain">;</span>
&lt;<span class="cwebmacro">See if the second option is "not" plus an existing property</span> <span class="cwebmacronumber">5.8.2</span>&gt;<span class="plain">;</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">alreadybar</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">EW</span><span class="plain">)) </span><span class="identifier">alreadybar</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
&lt;<span class="cwebmacro">See if the second option already means something incompatible with this</span> <span class="cwebmacronumber">5.8.3</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">error_text</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">EW</span><span class="plain">);</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">error_text</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_MiscellaneousEOProblem</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, you proposed the new either/or property '%2': but %3."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_8_1"></a><b>&#167;5.8.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">See if the first option already means something incompatible with this</span> <span class="cwebmacronumber">5.8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">already</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">already</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">error_text</span><span class="plain"> = </span><span class="string">"this already has a meaning as a value property"</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"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">FW</span><span class="plain">)) {</span>
<span class="identifier">parse_node</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">error_text</span><span class="plain"> = </span><span class="string">"this already has a meaning"</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="#SP5_8">&#167;5.8</a>.</p>
<p class="inwebparagraph"><a id="SP5_8_2"></a><b>&#167;5.8.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">See if the second option is "not" plus an existing property</span> <span class="cwebmacronumber">5.8.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">negated</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt;(</span><span class="identifier">EW</span><span class="plain">)) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">EPW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">negated</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt;, 1);</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">not_what</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">EPW</span><span class="plain">)) </span><span class="identifier">not_what</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">not_what</span><span class="plain">) &amp;&amp; (</span><span class="identifier">not_what</span><span class="plain"> != </span><span class="identifier">already</span><span class="plain">))</span>
<span class="identifier">error_text</span><span class="plain"> =</span>
<span class="string">"this is 'not' compounded with an existing either/or "</span>
<span class="string">"property, which would cause horrible ambiguities"</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_8">&#167;5.8</a>.</p>
<p class="inwebparagraph"><a id="SP5_8_3"></a><b>&#167;5.8.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">See if the second option already means something incompatible with this</span> <span class="cwebmacronumber">5.8.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">alreadybar</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">alreadybar</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">error_text</span><span class="plain"> = </span><span class="string">"this already has a meaning as a value property"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">already</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Properties::EitherOr::get_negation</span><span class="plain">(</span><span class="identifier">already</span><span class="plain">) != </span><span class="identifier">alreadybar</span><span class="plain">))</span>
<span class="identifier">error_text</span><span class="plain"> = </span><span class="string">"this is not the same negation as the last "</span>
<span class="string">"time this either/or property was used"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">already</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="functiontext">Properties::EitherOr::get_negation</span><span class="plain">(</span><span class="identifier">already</span><span class="plain">) != </span><span class="identifier">alreadybar</span><span class="plain">))</span>
<span class="identifier">error_text</span><span class="plain"> =</span>
<span class="string">"this already has a meaning as an either/or property"</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"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">EW</span><span class="plain">)) {</span>
<span class="identifier">parse_node</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">error_text</span><span class="plain"> = </span><span class="string">"this already has a meaning"</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="#SP5_8">&#167;5.8</a>.</p>
<p class="inwebparagraph"><a id="SP5_9"></a><b>&#167;5.9. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create the property and have the new owner provide it</span> <span class="cwebmacronumber">5.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> &lt;= 2) </span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Properties::EitherOr::obtain</span><span class="plain">(</span><span class="identifier">FW</span><span class="plain">, </span><span class="identifier">owner_infs</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Properties::Conditions::new</span><span class="plain">(</span><span class="identifier">owner_infs</span><span class="plain">, </span><span class="identifier">CNW</span><span class="plain">, </span><span class="identifier">the_list</span><span class="plain">,</span>
<span class="plain">&amp;</span><span class="identifier">already_created_instances</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span><span class="functiontext">Calculus::Propositions::Abstract::to_provide_property</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">),</span>
<span class="identifier">owner_infs</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_10"></a><b>&#167;5.10. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make the second option an either/or property which negates the first</span> <span class="cwebmacronumber">5.10</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prnbar</span><span class="plain"> = </span><span class="functiontext">Properties::EitherOr::obtain</span><span class="plain">(</span><span class="identifier">SW</span><span class="plain">, </span><span class="identifier">owner_infs</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span><span class="functiontext">Calculus::Propositions::Abstract::to_provide_property</span><span class="plain">(</span><span class="identifier">prnbar</span><span class="plain">),</span>
<span class="identifier">owner_infs</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="functiontext">Properties::EitherOr::make_negations</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">prnbar</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_11"></a><b>&#167;5.11. </b>An interesting anomaly in the language here is that when an either/or
pair is created, like so:
</p>
<blockquote>
<p>A vehicle can be speedy or sluggish.</p>
</blockquote>
<p class="inwebparagraph">the convention is that the first-named term is the more surprising one,
so that the default is the second. That seems natural, because if there's
just one named alternative, like this:
</p>
<blockquote>
<p>A vehicle can be fabulously racy.</p>
</blockquote>
<p class="inwebparagraph">then the default is for this property not to be had. But when there are
three or more alternatives, like so:
</p>
<blockquote>
<p>A vehicle can be petrol, diesel, electric or hybrid.</p>
</blockquote>
<p class="inwebparagraph">the default is the first option &mdash; petrol. This accords with the
convention that the first-created value for an enumerated kind is always
its default value.
</p>
<p class="inwebparagraph">But the beta-testers felt that this was an anomaly in the language. I
suspect they're right, but it isn't obvious to me what a better system
would be. And there does seem to be some subtle difference in English
meaning as to the suggested likelihood of possibilities, here. "You can
be useful" has the sense that you aren't useful right at the moment,
but "it can be blue, green or purple" tends to favour the front end
of the list as likelier, if anything &mdash; as when people offer an
exaggeratedly unlikely final choice: "you can be black, white, brown,
or sky blue pink".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Make the three or more options the range of possibilities for this new kind</span> <span class="cwebmacronumber">5.11</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">option</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">condition_kind</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">option</span><span class="plain"> = </span><span class="identifier">the_list</span><span class="plain">; </span><span class="identifier">option</span><span class="plain">; </span><span class="identifier">option</span><span class="plain"> = (</span><span class="identifier">option</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">)?(</span><span class="identifier">option</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">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="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">option</span><span class="plain">) == </span><span class="identifier">AND_NT</span><span class="plain">)</span>
<span class="identifier">PW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">option</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">PW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">option</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Disallow this option name if it clashes with something non-adjectival</span> <span class="cwebmacronumber">5.11.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Disallow this option name if it clashes with an either-or</span> <span class="cwebmacronumber">5.11.2</span>&gt;<span class="plain">;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Abstract::to_create_something</span><span class="plain">(</span><span class="identifier">condition_kind</span><span class="plain">, </span><span class="identifier">PW</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_11_1"></a><b>&#167;5.11.1. </b>The interesting thing here is that we do allow name-clashes with either/or
properties, with other condition values (since those are adjectival and
therefore parse to description specifications), and indeed adjectives
in general. What we don't want is for it to clash with a noun, because then
there would be horrible ambiguities in parsing.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Disallow this option name if it clashes with something non-adjectival</span> <span class="cwebmacronumber">5.11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">PW</span><span class="plain">)) {</span>
<span class="identifier">parse_node</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="reserved">int</span><span class="plain"> </span><span class="identifier">exempt</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Descriptions::is_qualified</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))) </span><span class="identifier">exempt</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="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_property</span><span class="plain">)) </span><span class="identifier">exempt</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">exempt</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">"Already means: $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">PW</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_spec</span><span class="plain">(3, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyAlreadyKnown</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, one of the values you supply as a possibility is '%2', but this "</span>
<span class="string">"already has a meaning (as %3)."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_11">&#167;5.11</a>.</p>
<p class="inwebparagraph"><a id="SP5_11_2"></a><b>&#167;5.11.2. </b>And similarly:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Disallow this option name if it clashes with an either-or</span> <span class="cwebmacronumber">5.11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">already</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">PW</span><span class="plain">)) </span><span class="identifier">already</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">already</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">already</span><span class="plain">))) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">PW</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_EOClashesWithCondition</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, one of the values you supply as a possibility is '%2', but this "</span>
<span class="string">"already has a meaning as an either-or property. The same adjective "</span>
<span class="string">"can't be used both ways, so you'll have to use a different word here."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_11">&#167;5.11</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. X has a K called P. </b>The following handles sentences like
</p>
<blockquote>
<p>A container has a number called rating.</p>
</blockquote>
<p class="inwebparagraph">in which the "number called rating" construction is a <code class="display"><span class="extract">PROPERTYCALLED_NT</span></code>
subtree, and also sentences like
</p>
<blockquote>
<p>A fruit has a colour.</p>
</blockquote>
<p class="inwebparagraph">in which there's only a leaf on the left-hand-side &mdash; in fact an <code class="display"><span class="extract">PROPER_NOUN_NT</span></code>
node, though of course it's not an object. This is most neatly handled with
a recursive traverse of the left-hand subtree.
</p>
<p class="inwebparagraph">(There's no sentence-handler here since "to have" has been implemented already.)
</p>
<pre class="display">
<span class="reserved">property</span><span class="plain"> *</span><span class="functiontext">Assertions::Property::recursively_declare_properties</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner_ref</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">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="identifier">AND_NT</span><span class="plain">:</span>
<span class="functiontext">Assertions::Property::recursively_declare_properties</span><span class="plain">(</span><span class="identifier">owner_ref</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::Property::recursively_declare_properties</span><span class="plain">(</span><span class="identifier">owner_ref</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">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROPERTYCALLED_NT</span><span class="plain">: </span>&lt;<span class="cwebmacro">This is a subtree citing a kind of value plus a name</span> <span class="cwebmacronumber">6.2</span>&gt;<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">This is a leaf containing just a property name</span> <span class="cwebmacronumber">6.1</span>&gt;<span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Assertions::Property::recursively_declare_properties on a node of unknown type"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Property::recursively_declare_properties is used in <a href="#SP7_1">&#167;7.1</a>, 9/ma (<a href="9-ma.html#SP3_3_25">&#167;3.3.25</a>).</p>
<p class="inwebparagraph"><a id="SP6_1"></a><b>&#167;6.1. </b>Note that the property name may not yet exist; in which case the following
automatically creates it.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">This is a leaf containing just a property name</span> <span class="cwebmacronumber">6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</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">rp</span><span class="plain">&gt;&gt; == </span><span class="identifier">K_number</span><span class="plain">) || (&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt; == </span><span class="identifier">K_text</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::assertion_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BareProperty</span><span class="plain">),</span>
<span class="string">"this would create a property called 'number' or 'text'"</span><span class="plain">,</span>
<span class="string">"and although bare names of kinds are usually allowed as properties, "</span>
<span class="string">"these aren't. Instead, try '... has a number called position.' or "</span>
<span class="string">"something like that, to give the property a name."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">owner_infs</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">owner_ref</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">owner_infs</span><span class="plain">);</span>
<span class="identifier">Kinds::Behaviour::convert_to_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">); </span> <span class="comment">if that's possible; does nothing if not</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Behaviour::has_properties</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Disallow this kind as a new owner of a value property</span> <span class="cwebmacronumber">6.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::obtain</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="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span><span class="functiontext">Calculus::Propositions::Abstract::to_provide_property</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">),</span>
<span class="identifier">owner_infs</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">prn</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_1_1"></a><b>&#167;6.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Disallow this kind as a new owner of a value property</span> <span class="cwebmacronumber">6.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_action_name</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">CON_activity</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">CON_rulebook</span><span class="plain">))</span>
<span class="identifier">Problems::Issue::assertion_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ValueCantHaveVProperties2</span><span class="plain">),</span>
<span class="string">"this is a kind of value which is not allowed to have properties of its own"</span><span class="plain">,</span>
<span class="string">"because this would cause confusion with variables, which are more useful in "</span>
<span class="string">"most cases. (See the Kinds index for which kinds can have properties.)"</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">Problems::Issue::assertion_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ValueCantHaveVProperties</span><span class="plain">),</span>
<span class="string">"this is a kind of value which is not allowed to have properties of its own"</span><span class="plain">,</span>
<span class="string">"because this would be impossible to store in any sensible way. For instance, "</span>
<span class="string">"'A scene has a number called difficulty.' is fine because there are not many "</span>
<span class="string">"scenes and I know them all, but 'A number has a text called French translation.' "</span>
<span class="string">"is not allowed, because storing something for every possible number takes an "</span>
<span class="string">"impossible amount of space. (See the Kinds index for which kinds can have "</span>
<span class="string">"properties.)"</span><span class="plain">);</span>
<span class="identifier">owner_infs</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_1">&#167;6.1</a>.</p>
<p class="inwebparagraph"><a id="SP6_2"></a><b>&#167;6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">This is a subtree citing a kind of value plus a name</span> <span class="cwebmacronumber">6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">kind_ref</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">prn_ref</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::Property::recursively_call_properties</span><span class="plain">(</span><span class="identifier">owner_ref</span><span class="plain">, </span><span class="identifier">kind_ref</span><span class="plain">, </span><span class="identifier">prn_ref</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The following handles a second kind of recursion: using "and" to divide
several property names, e.g., in
</p>
<blockquote>
<p>A door has numbers called length and width.</p>
</blockquote>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Property::recursively_call_properties</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner_ref</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">kind_ref</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">prn_ref</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">prn_ref</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">AND_NT</span><span class="plain">:</span>
<span class="functiontext">Assertions::Property::recursively_call_properties</span><span class="plain">(</span><span class="identifier">owner_ref</span><span class="plain">, </span><span class="identifier">kind_ref</span><span class="plain">, </span><span class="identifier">prn_ref</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">);</span>
<span class="functiontext">Assertions::Property::recursively_call_properties</span><span class="plain">(</span><span class="identifier">owner_ref</span><span class="plain">, </span><span class="identifier">kind_ref</span><span class="plain">, </span><span class="identifier">prn_ref</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">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
&lt;<span class="cwebmacro">Deal with an individual property being declared</span> <span class="cwebmacronumber">7.1</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::Property::recursively_call_properties is used in <a href="#SP6_2">&#167;6.2</a>.</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Deal with an individual property being declared</span> <span class="cwebmacronumber">7.1</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="functiontext">Assertions::Property::recursively_declare_properties</span><span class="plain">(</span><span class="identifier">owner_ref</span><span class="plain">, </span><span class="identifier">prn_ref</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Find the kind of value being asked for</span> <span class="cwebmacronumber">7.1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Issue a problem message if the property kind is just "value"</span> <span class="cwebmacronumber">7.1.2</span>&gt;<span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">current_kind</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="functiontext">Properties::Valued::set_kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">current_kind</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem message for giving the wrong kind of an existing property</span> <span class="cwebmacronumber">7.1.3</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_1_1"></a><b>&#167;7.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Find the kind of value being asked for</span> <span class="cwebmacronumber">7.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</span><span class="plain">))) </span><span class="identifier">K</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a problem message for a non-kind as the property kind</span> <span class="cwebmacronumber">7.1.1.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<p class="inwebparagraph"><a id="SP7_1_1_1"></a><b>&#167;7.1.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for a non-kind as the property kind</span> <span class="cwebmacronumber">7.1.1.1</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>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</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="identifier">LOG</span><span class="plain">(</span><span class="string">"Offending SP: $T"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_new_variable_like</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RedundantThatVaries</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which I am reading as a request to make a new named property - "</span>
<span class="string">"a value associated with an object and which has a name. But you write this "</span>
<span class="string">"as if it were a variable, which is not allowed because it would confuse "</span>
<span class="string">"things. For example, 'A scene has a number that varies called the completion "</span>
<span class="string">"bonus.' is not allowed - it should just be 'A scene has a number called "</span>
<span class="string">"the completion bonus.', that is, without the 'that varies'."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyTooSpecific</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which I am reading as a request to make a new named property - "</span>
<span class="string">"a value associated with an object and which has a name. The request seems to "</span>
<span class="string">"say that the value in question is '%2', but this is too specific a description. "</span>
<span class="string">"(Instead, a kind of value (such as 'number') or a kind of object (such as 'room' "</span>
<span class="string">"or 'thing') should be given. To get a property whose contents can be any kind "</span>
<span class="string">"of object, use 'object'.)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyKindUnknown</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but '%2' is not the name of a kind of value which I know (such "</span>
<span class="string">"as 'number' or 'text')."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7_1_1">&#167;7.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP7_1_2"></a><b>&#167;7.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message if the property kind is just "value"</span> <span class="cwebmacronumber">7.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">P_variable_initial_value</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyKindVague</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but saying that a property is a 'value' does not give me a clear "</span>
<span class="string">"enough idea what it will hold. You need to say what kind of value: for instance, "</span>
<span class="string">"'A door has a number called street address.' is allowed because 'number' is "</span>
<span class="string">"specific about the kind of value."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<p class="inwebparagraph"><a id="SP7_1_3"></a><b>&#167;7.1.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for giving the wrong kind of an existing property</span> <span class="cwebmacronumber">7.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">kind_ref</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(3, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">current_kind</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PropertyKindClashes</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but '%2' contradicts what I previously thought about the property "</span>
<span class="string">"%3, which was that it was %4."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7_1">&#167;7.1</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="9-imp.html">Back to 'Implications'</a></li><li><i>(This section ends Chapter 9: The A-Parser.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>