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-tbath.html
2020-04-07 01:06:09 +01:00

440 lines
44 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>9/tfa</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '9/tbath' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#9">Chapter 9: The A-Parser</a></li><li><b>To Be and To Have</b></li></ul><p class="purpose">To handle sentences with primary verb "to be" or "to have".</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>"To Be and To Have" ought to be the name of an incomprehensible
book by Sartre which dismisses Heidegger's seminal "To Have and To Be",
or something like that, but instead it is the name of a section which contains
the most important sentence handler: the one for assertions.
</p>
<p class="inwebparagraph">This will turn out to be quite a lot of work, occupying four sections of
code in all. For etymological reasons, the English verb "to be" is a mixture
of several different verbs which have blurred together into one: consider "I
am 5", "I am happy" and "I am Chloe". Even the definition occupies some
12 columns of the "Oxford English Dictionary" and they make interesting
reading in clarifying the problem. Most computer programming languages
implement only <code class="display"><span class="extract">=</span></code> and <code class="display"><span class="extract">==</span></code>, which correspond to OED's meaning 10, "to exist
as the thing known by a certain name; to be identical with". But Inform
implements a much broader set of meanings. For example, its distinction
between spatial and property knowledge reflects the OED's distinction between
meanings 5a ("to have or occupy a place somewhere") and 9b ("to have a
place among the things distinguished by a specified quality") respectively.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Here, and in the sections which follow, we conventionally write <code class="display"><span class="extract">px</span></code> and
<code class="display"><span class="extract">py</span></code> for the subtrees representing subject and object sides of the verb. Thus
</p>
<blockquote>
<p>The white marble is in the bamboo box.</p>
</blockquote>
<p class="inwebparagraph">will result in <code class="display"><span class="extract">px</span></code> representing "white marble" and <code class="display"><span class="extract">py</span></code> "in the bamboo
box" (not just a leaf, since it will be a tree showing the containment
relationship as well as the noun).
</p>
<pre class="display">
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">ASSERT_SH_handler</span><span class="plain"> = { </span><span class="identifier">SENTENCE_NT</span><span class="plain">, </span><span class="constant">ASSERT_VB</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="functiontext">Assertions::Copular::assertion</span><span class="plain"> };</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Copular::assertion</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">pv</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="identifier">possessive_verb_ANNOT</span><span class="plain">))</span>
<span class="functiontext">Assertions::Copular::to_have</span><span class="plain">(</span><span class="identifier">pv</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Assertions::Copular::to_be</span><span class="plain">(</span><span class="identifier">pv</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Copular::to_be</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pv</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">px</span><span class="plain"> = </span><span class="identifier">pv</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain"> = </span><span class="identifier">pv</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="identifier">next</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">)) &gt; </span><span class="constant">1</span><span class="plain">)</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">Vocabulary::test_flags</span><span class="plain">(</span>
<span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">)), </span><span class="identifier">TEXT_MC</span><span class="plain">+</span><span class="identifier">TEXTWITHSUBS_MC</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TextNotClosing</span><span class="plain">),</span>
<span class="string">"it looks as if perhaps you did not intend that to read as a "</span>
<span class="string">"single sentence"</span><span class="plain">,</span>
<span class="string">"and possibly the text in quotes was supposed to stand as "</span>
<span class="string">"as a sentence on its own? (The convention is that if text "</span>
<span class="string">"ends in a full stop, exclamation or question mark, perhaps "</span>
<span class="string">"with a close bracket or quotation mark involved as well, then "</span>
<span class="string">"that punctuation mark also closes the sentence to which the "</span>
<span class="string">"text belongs: but otherwise the words following the quoted "</span>
<span class="string">"text are considered part of the same sentence.)"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Assertions::Copular::make_assertion</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">py</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Copular::assertion appears nowhere else.</p>
<p class="endnote">The function Assertions::Copular::to_be is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>"To have" may seem as if it ought to be an entirely different verb from
"to be", but in fact they have heavily overlapping meanings, and we will
implement them with a great deal of common code. (English is unusual in the
way that "to be" has taken over some of the functions which "to have"
has in other languages &mdash; compare the French "j'ai fatigu\'e", literally
"I have tired" rather than "I am tired", which is arguably more logical
since it talks about the possession of a property.)
</p>
<p class="inwebparagraph">On traverse 1 we therefore alter the tree judiciously to convert any use of
"to have" into a use of "to be"; it follows that <code class="display"><span class="extract">Assertions::Copular::to_have</span></code> can never be
called in traverse 2, when there are no uses of "to have" left in the tree.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Copular::to_have</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pv</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">px</span><span class="plain"> = </span><span class="identifier">pv</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain"> = </span><span class="identifier">pv</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="identifier">next</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Reject two ungrammatical forms of "to have"</span> <span class="cwebmacronumber">4.1</span>&gt;<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">py</span><span class="plain">) == </span><span class="identifier">CALLED_NT</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Handle "X has an A called B"</span> <span class="cwebmacronumber">4.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><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">py</span><span class="plain">)))</span>
&lt;<span class="cwebmacro">Handle "X has a V" where V is a kind of value which is also a property</span> <span class="cwebmacronumber">4.3</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Handle "X has P" where P is a list of properties</span> <span class="cwebmacronumber">4.4</span>&gt;<span class="plain">;</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">pv</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="identifier">possessive_verb_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="functiontext">Assertions::Copular::to_be</span><span class="plain">(</span><span class="identifier">pv</span><span class="plain">); </span><span class="comment">and start again as if it had never been possessive</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Copular::to_have is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Reject two ungrammatical forms of "to have"</span> <span class="cwebmacronumber">4.1</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">py</span><span class="plain">) == </span><span class="constant">X_OF_Y_NT</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SuperfluousOf</span><span class="plain">),</span>
<span class="string">"the 'of' here appears superfluous"</span><span class="plain">,</span>
<span class="string">"assuming the sentence aims to give a property value of something. "</span>
<span class="string">"(For instance, if we want to declare the carrying capacity of "</span>
<span class="string">"something, the normal Inform practice is to say 'The box has "</span>
<span class="string">"carrying capacity 10' rather than 'The box has a carrying capacity "</span>
<span class="string">"of 10'.)"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</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="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SuperfluousWith</span><span class="plain">),</span>
<span class="string">"the 'has ... with' here appears to be a mixture of two ways to "</span>
<span class="string">"give something properties"</span><span class="plain">,</span>
<span class="string">"that is, 'The box is a container with capacity 10.' and 'The box "</span>
<span class="string">"has capacity 10.'"</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="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b>Here <code class="display"><span class="extract">py</span></code> is a <code class="display"><span class="extract">CALLED_NT</span></code> subtree for "an A called B", which we relabel
as a <code class="display"><span class="extract">PROPERTYCALLED_NT</span></code> subtree and hang beneath an <code class="display"><span class="extract">ALLOWED_NT</span></code> node.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle "X has an A called B"</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">), </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SuperfluousCalled</span><span class="plain">),</span>
<span class="string">"'called' should be used only when the name is different from the kind"</span><span class="plain">,</span>
<span class="string">"so this sentence should be simplified. For example, 'A door has a "</span>
<span class="string">"colour called colour' should be written more simply as 'A door has "</span>
<span class="string">"a colour'; but 'called' can be used for something like 'A door has "</span>
<span class="string">"a number called the street number'."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">, </span><span class="constant">PROPERTYCALLED_NT</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">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) == </span><span class="identifier">AND_NT</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">ParseTree::left_edge_of</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">),</span>
<span class="identifier">R</span><span class="plain"> = </span><span class="identifier">ParseTree::right_edge_of</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="identifier">down</span><span class="plain">);</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">&gt;(</span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">));</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain"> = </span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">;</span>
<span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Thus $T"</span><span class="plain">, </span><span class="identifier">py</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">px</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">ALLOWED_NT</span><span class="plain">);</span>
<span class="identifier">px</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="identifier">down</span><span class="plain"> = </span><span class="identifier">py</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">prohibited</span><span class="plain"> = &lt;</span><span class="identifier">prohibited</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">px</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (!</span><span class="identifier">prohibited</span><span class="plain">) {</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">));</span>
<span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="identifier">next</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">py</span><span class="plain"> = </span><span class="identifier">px</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_3"></a><b>&#167;4.3. </b>More directly, here we simply relegate <code class="display"><span class="extract">py</span></code> by hanging it from a new <code class="display"><span class="extract">ALLOWED_NT</span></code>
node. This is for something like
</p>
<blockquote>
<p>A thing has a colour.</p>
</blockquote>
<p class="inwebparagraph">where "colour" is the name of both a kind of value and (soon) a property.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle "X has a V" where V is a kind of value which is also a property</span> <span class="cwebmacronumber">4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">px</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">ALLOWED_NT</span><span class="plain">);</span>
<span class="identifier">px</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="identifier">down</span><span class="plain"> = </span><span class="identifier">py</span><span class="plain">;</span>
<span class="identifier">py</span><span class="plain"> = </span><span class="identifier">px</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_4"></a><b>&#167;4.4. </b>And here we just mark <code class="display"><span class="extract">py</span></code> as a property list. Typically the sentence would
be "The player has carrying capacity 7."
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle "X has P" where P is a list of properties</span> <span class="cwebmacronumber">4.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">, </span><span class="identifier">PROPERTY_LIST_NT</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>In either case, then, we end up going through <code class="display"><span class="extract">Assertions::Copular::to_be</span></code> and then to the
following routine, which asserts that subtree <code class="display"><span class="extract">px</span></code> "is" <code class="display"><span class="extract">py</span></code>.
</p>
<p class="inwebparagraph">During traverse 1, this takes place in a three-stage process:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) The two subtrees are each individually "refined", which clarifies the
meaning of the noun phrases used in them, and tidies up the tree (see
"Refine Parse Tree").
</li></ul>
<ul class="items"><li>(b) The Creator is invited to create new objects, variables and so on to
ensure that unrecognised noun phrases are made meaningful (see "The Creator").
</li></ul>
<ul class="items"><li>(c) In a "there is X" sentence, where <code class="display"><span class="extract">px</span></code> is a meaningless placeholder,
we cause X to be created, but otherwise do nothing; otherwise, we call
the massive <code class="display"><span class="extract">Assertions::Maker::make_assertion_recursive</span></code> routine (see "Make Assertions").
</li></ul>
<p class="inwebparagraph">In traverse 2, only (c) takes place; (a) and (b) are one-time events.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Copular::make_assertion</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pc</span><span class="plain"> = </span><span class="identifier">problem_count</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">existential</span><span class="plain">-</span><span class="identifier">np</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">))))</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">, </span><span class="constant">ALLOW_CREATION</span><span class="plain">);</span>
<span class="functiontext">Assertions::Refiner::refine</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">, </span><span class="constant">ALLOW_CREATION</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> &gt; </span><span class="identifier">pc</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Assertions::Creator::consult_the_creator</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">py</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_sentences</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">existential</span><span class="plain">-</span><span class="identifier">np</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="functiontext">Assertions::Copular::make_existential_assertion</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">);</span>
<span class="identifier">px</span><span class="plain"> = </span><span class="identifier">py</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Assertions::Maker::make_assertion_recursive</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">py</span><span class="plain">);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Change the discussion topic for subsequent sentences</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Copular::make_assertion is used in <a href="#SP3">&#167;3</a>, 19/tod (<a href="19-tod.html#SP6_3">&#167;6.3</a>).</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b>The slight asymmetry in what follows is partly pragmatic, partly the result
of subject-verb inversion ("in the bag is the ball" not "the ball is in the
bag"). We extract a subject from a relationship node on the left, but not on
the right, and we don't extract an object from one. Consider:
</p>
<blockquote>
<p>A billiards table is in the Gazebo. On it is a trophy cup.</p>
</blockquote>
<p class="inwebparagraph">What does "it" mean, and why? A human reader goes for the billiards table at
once, because it seems more likely as a supporter than the Gazebo, but that's
not how Inform gets the same answer. It all hangs on "billiards table" being
the object of the first sentence, not the Gazebo; if we descended the RHS,
which is <code class="display"><span class="extract">RELATIONSHIP_NT -&gt; PROPER_NOUN_NT</span></code> pointing to the Gazebo, that's the
conclusion we would have reached.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Change the discussion topic for subsequent sentences</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infsx</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">infsy</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">infsy_full</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">infsx</span><span class="plain"> = </span><span class="functiontext">Assertions::Copular::discussed_at_node</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">);</span>
<span class="identifier">infsy_full</span><span class="plain"> = </span><span class="functiontext">Assertions::Copular::discussed_at_node</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">) != </span><span class="identifier">KIND_NT</span><span class="plain">) </span><span class="identifier">infsy</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">);</span>
<span class="functiontext">Assertions::Traverse::change_discussion_topic</span><span class="plain">(</span><span class="identifier">infsx</span><span class="plain">, </span><span class="identifier">infsy</span><span class="plain">, </span><span class="identifier">infsy_full</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">px</span><span class="plain">) == </span><span class="identifier">AND_NT</span><span class="plain">) </span><span class="functiontext">Assertions::Traverse::subject_of_discussion_a_list</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="constant">clears_pronouns_ANNOT</span><span class="plain">))</span>
<span class="functiontext">Assertions::Traverse::new_discussion</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="SP6"></a><b>&#167;6. </b></p>
<pre class="display">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">Assertions::Copular::discussed_at_node</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">) != </span><span class="identifier">KIND_NT</span><span class="plain">) </span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">) == </span><span class="identifier">RELATIONSHIP_NT</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) == </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">))</span>
<span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</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">pn</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) == </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">))</span>
<span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">infs</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Copular::discussed_at_node is used in <a href="#SP5_1">&#167;5.1</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Copular::make_existential_assertion</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Copular::make_existential_assertion</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">) == </span><span class="identifier">AND_NT</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Copular::make_existential_assertion</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="functiontext">Assertions::Copular::make_existential_assertion</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">) == </span><span class="constant">COMMON_NOUN_NT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">InferenceSubjects::is_a_kind_of_object</span><span class="plain">(</span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">))) ||</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K_object</span><span class="plain">, </span><span class="functiontext">InferenceSubjects::as_kind</span><span class="plain">(</span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">)))))</span>
<span class="functiontext">Assertions::Creator::convert_instance_to_nounphrase</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ThereIsVague</span><span class="plain">),</span>
<span class="string">"'there is...' can only be used to create objects"</span><span class="plain">,</span>
<span class="string">"and not instances of other kinds.'"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Copular::make_existential_assertion is used in <a href="#SP5">&#167;5</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="9-tfa.html">Back to 'Traverse for Assertions'</a></li><li><a href="9-rpt.html">Continue with 'Refine Parse Tree'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>