mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
440 lines
44 KiB
HTML
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">§1. Definitions</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§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>§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">-></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">-></span><span class="element">down</span><span class="plain">-></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">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">-></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">)) > </span><span class="constant">1</span><span class="plain">)</span>
|
|
<span class="plain">&& (</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">§4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§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 — 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">-></span><span class="element">down</span><span class="plain">-></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">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">-></span><span class="identifier">next</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Reject two ungrammatical forms of "to have"</span> <span class="cwebmacronumber">4.1</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">CALLED_NT</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Handle "X has an A called B"</span> <span class="cwebmacronumber">4.2</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">)))</span>
|
|
<<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>>
|
|
<span class="reserved">else</span>
|
|
<<span class="cwebmacro">Handle "X has P" where P is a list of properties</span> <span class="cwebmacronumber">4.4</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">pv</span><span class="plain">-></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">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4_1"></a><b>§4.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Reject two ungrammatical forms of "to have"</span> <span class="cwebmacronumber">4.1</span>> =
|
|
</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">§4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Handle "X has an A called B"</span> <span class="cwebmacronumber">4.2</span>> =
|
|
</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">-></span><span class="element">down</span><span class="plain">-></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">-></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">-></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">-></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">-></span><span class="identifier">down</span><span class="plain">);</span>
|
|
<span class="plain"><</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">>(</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"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</span>
|
|
<span class="identifier">pn</span><span class="plain">-></span><span class="element">next</span><span class="plain"> = </span><span class="identifier">py</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">;</span>
|
|
<span class="identifier">py</span><span class="plain">-></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">-></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">-></span><span class="element">next</span><span class="plain">-></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"> = <</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">>(</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"><</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">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">));</span>
|
|
<span class="identifier">py</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="identifier">next</span><span class="plain"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</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">-></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">§4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4_3"></a><b>§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">
|
|
<<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>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">px</span><span class="plain">-></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">-></span><span class="element">next</span><span class="plain">-></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">-></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">§4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Handle "X has P" where P is a list of properties</span> <span class="cwebmacronumber">4.4</span>> =
|
|
</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">§4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§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"> (!(<</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">>(</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"> > </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"> (<</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">>(</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>
|
|
<<span class="cwebmacro">Change the discussion topic for subsequent sentences</span> <span class="cwebmacronumber">5.1</span>><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">§3</a>, 19/tod (<a href="19-tod.html#SP6_3">§6.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_1"></a><b>§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 -> PROPER_NOUN_NT</span></code> pointing to the Gazebo, that's the
|
|
conclusion we would have reached.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Change the discussion topic for subsequent sentences</span> <span class="cwebmacronumber">5.1</span>> =
|
|
</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">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§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">) && (</span><span class="identifier">pn</span><span class="plain">-></span><span class="element">down</span><span class="plain">) &&</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="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">-></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">) && (</span><span class="identifier">pn</span><span class="plain">-></span><span class="element">down</span><span class="plain">) &&</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="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">-></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">§5.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§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">-></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">-></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">-></span><span class="element">down</span><span class="plain">-></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">§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>
|
|
|