mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
1038 lines
94 KiB
HTML
1038 lines
94 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>11/tc</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 '11/sc' 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#11">Chapter 11: Predicate Calculus</a></li><li><b>Sentence Conversions</b></li></ul><p class="purpose">The third of the three sources of propositions to conjure with: those which arise by the parsing of complex sentence trees in the S-grammar.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. The meaning of a sentence</a></li><li><a href="#SP1_14">§1.14. Simplification</a></li><li><a href="#SP3">§3. The meaning of a noun phrase</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. The meaning of a sentence. </b>This section provides a single, but crucial, function to the rest of Inform:
|
|
it takes a sentence subtree output by the S-parser and turns it into a proposition.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The sentence subtree can be headed by either a <code class="display"><span class="extract">SV_NT</span></code>, representing a
|
|
whole sentence, which we turn into a proposition with no free variables; or by
|
|
an <code class="display"><span class="extract">SN_NT</span></code>, representing a description which includes a relative clause,
|
|
such as "an animal which can see the player". In this section we will loosely
|
|
refer to the text parsed by either sort of subtree as the "sentence".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The basic idea is simple. The sentence will have a verb phrase (VP), together
|
|
with two noun phrases: a subject phrase (SP) and object phrase (OP). English
|
|
is an SVO language, so phrases (usually) occur in the sequence SP-VP-OP.
|
|
In "Katy examines the painting", "Katy" is the SP and "painting" is
|
|
the OP. (Although the subject is sometimes the more active participant, that
|
|
isn't always the case: in "the painting is examined by Katy", "the painting"
|
|
is now the SP. The subject is what the sentence talks about.) At this point
|
|
in the program, the S-parser has turned the sentence into a neat tree structure
|
|
identifying the SP, VP and OP. We need to find meanings for the SP, VP and OP
|
|
independently, and then combine these into a single proposition representing
|
|
the meaning of the whole sentence.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">conv_log_depth</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="comment">recursion depth: used only to clarify the debugging log</span>
|
|
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Calculus::Propositions::FromSentences::S_subtree</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">SV_not_SN</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">, </span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">subject_of_sentence</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">verb_phrase_negated</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">subject_phrase_subtree</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">object_phrase_subtree</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">subject_phrase_prop</span><span class="plain">, *</span><span class="identifier">object_phrase_prop</span><span class="plain">;</span>
|
|
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">subject_phrase_term</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">); </span><span class="comment">unnecessary initialization to pacify clang, which can't prove it's unnecessary</span>
|
|
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">object_phrase_term</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">verb_phrase_relation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Check the tree position makes sense, and tell the debugging log</span> <span class="cwebmacronumber">1.1</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Handle a THERE subtree, used for "there is/are NP"</span> <span class="cwebmacronumber">1.3</span>><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<<span class="cwebmacro">Find meaning of the VP as a relation and a parity</span> <span class="cwebmacronumber">1.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Find meanings of the SP and OP as propositions and terms</span> <span class="cwebmacronumber">1.8</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Bind up any free variable in the OP and sometimes the SP, too</span> <span class="cwebmacronumber">1.9</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Combine the SP, VP and OP meanings into a single proposition for the sentence</span> <span class="cwebmacronumber">1.13</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<<span class="cwebmacro">Simplify the resultant proposition</span> <span class="cwebmacronumber">1.14</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Tell the debugging log what the outcome of the sentence was</span> <span class="cwebmacronumber">1.2</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">A</span><span class="plain">) && (</span><span class="identifier">subject_of_sentence</span><span class="plain">)) *</span><span class="identifier">subject_of_sentence</span><span class="plain"> = </span><span class="identifier">subject_phrase_term</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sentence_prop</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Propositions::FromSentences::S_subtree is used in 10/varc (<a href="10-varc.html#SP13_3">§13.3</a>, <a href="10-varc.html#SP13_4">§13.4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_1"></a><b>§1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Check the tree position makes sense, and tell the debugging log</span> <span class="cwebmacronumber">1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">) </span><span class="identifier">Problems::Issue::s_subtree_error_set_position</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">A</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">conv_log_depth</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"-----------\n"</span><span class="plain">);</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">++;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] Starting fs on: <%W>\n"</span><span class="plain">, </span><span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_2"></a><b>§1.2. </b>And similarly, on the way out:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Tell the debugging log what the outcome of the sentence was</span> <span class="cwebmacronumber">1.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] fs: %W --> $D\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">sentence_prop</span><span class="plain">);</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">--;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_3"></a><b>§1.3. </b>The English verb "to be" has the syntactic quirk that it likes to have
|
|
both SP and OP, even when only when thing is being discussed. We say "it is
|
|
raining" and "there are seven continents", inserting "it" and "there"
|
|
even though they refer to nothing at all, because we don't like to say
|
|
"raining is" or "seven continents are".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">At any rate Inform parses a sentence in the form "There is X" or "There
|
|
are Y" into a simpler form of tree with just one noun phrase, and no verb
|
|
phrase at all. We convert the noun phrase to a proposition φ in which
|
|
x is free, then bind it with ∃ x to form ∃ x: φ(x),
|
|
making an S-proposition as required.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Handle a THERE subtree, used for "there is/are NP"</span> <span class="cwebmacronumber">1.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SV_not_SN</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"THERE subtree misplaced"</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">-></span><span class="element">down</span><span class="plain">;</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::from_spec</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::bind_existential</span><span class="plain">(</span><span class="identifier">sentence_prop</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="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_4"></a><b>§1.4. </b>Here we only locate the subject and object subtrees — their meanings we
|
|
leave for later — but we do find the content of the verb phrase. Given
|
|
the combination of verb and preposition usage (the latter optional), we
|
|
extract a binary predicate B. Note that we ignore the parity (whether
|
|
negated or not), because we've been told that from above.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Of course a VU also records the tense of the verb, but we ignore that here.
|
|
It has no effect on the proposition, only on the moment in history to which
|
|
it can be applied.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Find meaning of the VP as a relation and a parity</span> <span class="cwebmacronumber">1.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">subject_phrase_subtree</span><span class="plain"> = </span><span class="identifier">A</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subject_phrase_subtree</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Problems::Issue::s_subtree_error</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="string">"SP subtree null"</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">verb_phrase_subtree</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_phrase_subtree</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Problems::Issue::s_subtree_error</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="string">"VP subtree null"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_phrase_subtree</span><span class="plain">-></span><span class="element">down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Problems::Issue::s_subtree_error</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="string">"VP subtree broken"</span><span class="plain">);</span>
|
|
<span class="identifier">object_phrase_subtree</span><span class="plain"> = </span><span class="identifier">verb_phrase_subtree</span><span class="plain">-></span><span class="element">down</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">verb_usage</span><span class="plain"> *</span><span class="identifier">vu</span><span class="plain"> = </span><span class="identifier">ParseTree::get_vu</span><span class="plain">(</span><span class="identifier">verb_phrase_subtree</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vu</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Problems::Issue::s_subtree_error</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="string">"verb null"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">SV_not_SN</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) && (</span><span class="identifier">VerbUsages::get_tense_used</span><span class="plain">(</span><span class="identifier">vu</span><span class="plain">) != </span><span class="identifier">IS_TENSE</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Disallow the past tenses in relative clauses</span> <span class="cwebmacronumber">1.4.1</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">preposition_identity</span><span class="plain"> *</span><span class="identifier">prep</span><span class="plain"> = </span><span class="identifier">ParseTree::get_prep</span><span class="plain">(</span><span class="identifier">verb_phrase_subtree</span><span class="plain">);</span>
|
|
<span class="identifier">preposition_identity</span><span class="plain"> *</span><span class="identifier">second_prep</span><span class="plain"> = </span><span class="identifier">ParseTree::get_second_preposition</span><span class="plain">(</span><span class="identifier">verb_phrase_subtree</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">verb_phrase_relation</span><span class="plain"> = </span><span class="identifier">VerbUsages::get_regular_meaning</span><span class="plain">(</span><span class="identifier">vu</span><span class="plain">, </span><span class="identifier">prep</span><span class="plain">, </span><span class="identifier">second_prep</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_4_1"></a><b>§1.4.1. </b>A sad necessity:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Disallow the past tenses in relative clauses</span> <span class="cwebmacronumber">1.4.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">ExParser::Subtrees::throw_past_problem</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1_4">§1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_5"></a><b>§1.5. </b>First Rule. The "meaning" of a noun phrase is a pair (φ, t),
|
|
where φ is a proposition and t is a term. We read this as "t such
|
|
that φ is true". Exactly one of the following will always be true:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) If the NP talks about a single definite thing C, then t=C and φ = T,
|
|
the empty proposition.
|
|
</li><li>(b) If the NP talks about a single definite thing C but imposes conditions about its current
|
|
situation, then t=v for some variable v and φ = ∃ v: is(v, C)∧ψ
|
|
where ψ is a description of the conditions with no free variables and which
|
|
does not use v.
|
|
</li><li>(c) If the NP talks about a single but vague thing, identifying it only by its
|
|
current situation, then t=v for some variable v and φ is a proposition having
|
|
v as its unique free variable.
|
|
</li><li>(d) If the NP talks about a range, number or proportion of things, then t=v
|
|
for some variable v and φ = Qv : v∈{ v| ψ(v)}, where
|
|
v is the unique free variable of ψ, and Q is a generalised quantifier which
|
|
is not ∃.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP1_6"></a><b>§1.6. </b>As examples of all four cases:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) "Reverend Green" returns t=<code class="display"><span class="extract">Green</span></code>, φ = T — a single definite thing.
|
|
</li><li>(b) "Colonel Mustard in the Library" returns t=x such that
|
|
φ = ∃ x: is(x, <code class="display"><span class="extract">Mustard</span></code>)∧in(<code class="display"><span class="extract">Mustard</span></code>, <code class="display"><span class="extract">Library</span></code>) — a single definite
|
|
thing but subject to conditions.
|
|
</li><li>(c) "A suspect carrying the lead piping" returns t=x and
|
|
φ = suspect(x)∧carries(x, <code class="display"><span class="extract">piping</span></code>) — a single but vague thing.
|
|
</li><li>(d) "All the weapons in the Billiard Room" returns t=x and
|
|
φ = ∀ x: x∈{ x| weapon(x)∧in(x, <code class="display"><span class="extract">Billiard</span></code>)} —
|
|
a range of things.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP1_7"></a><b>§1.7. </b>Thus φ can contain at most 1 free variable, and then only in case (c).
|
|
But why does it do so at all? Why do we return "an open door" as
|
|
open(x)∧door(x)? It would be more consistent with the way we
|
|
handle "two open doors" to return it as ∃ x: open(x)∧door(x).
|
|
The answer is that if we were only parsing whole sentences (SV-trees) then
|
|
it would make no difference, because x ends up bound by ∃ x
|
|
anyway when the final sentence is being put together. But we also want to
|
|
parse descriptions. Consider:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>(1) let L be the list of open doors in the Dining Room;</p>
|
|
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<p>(2) let L be the list of two open doors in the Dining Room;</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">Here (1) is legal in Inform, (2) is not, because it implies a requirement about
|
|
the list which will probably not be satisfied. (Maybe there are three open
|
|
doors there, maybe none.) In case (1), <code class="display"><span class="extract">NPstp</span></code> applied to "open doors" will
|
|
return open(x)∧door(x), whose free variable x can
|
|
become any single object we might want to test for open-door-ness. But in
|
|
case (2), <code class="display"><span class="extract">NPstp</span></code> applied to "two open doors" will return
|
|
V_{=2} x: open(x)∧door(x), and here x is bound, and
|
|
can't be set equal to some object being tested.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Or to put this more informally: it's possible for a single item to be an
|
|
"open door", but it's not possible for a single item to be (say) "more
|
|
than three open doors". So φ contains a free variable if and only if
|
|
the NP describes a single but vague thing.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_8"></a><b>§1.8. </b>The First Rule is implemented by <code class="display"><span class="extract">Calculus::Propositions::FromSentences::NP_subtree_to_proposition</span></code> below, and
|
|
we apply it independently to the SP and OP:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Find meanings of the SP and OP as propositions and terms</span> <span class="cwebmacronumber">1.8</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">subject_K</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">verb_phrase_relation</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">subject_K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">subject_K</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">subject_phrase_prop</span><span class="plain"> =</span>
|
|
<span class="functiontext">Calculus::Propositions::FromSentences::NP_subtree_to_proposition</span><span class="plain">(&</span><span class="identifier">subject_phrase_term</span><span class="plain">, </span><span class="identifier">subject_phrase_subtree</span><span class="plain">,</span>
|
|
<span class="identifier">subject_K</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">object_K</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">verb_phrase_relation</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">object_K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">object_K</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">object_phrase_prop</span><span class="plain"> =</span>
|
|
<span class="functiontext">Calculus::Propositions::FromSentences::NP_subtree_to_proposition</span><span class="plain">(&</span><span class="identifier">object_phrase_term</span><span class="plain">, </span><span class="identifier">object_phrase_subtree</span><span class="plain">,</span>
|
|
<span class="identifier">object_K</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] subject NP: $0 such that: $D\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, &</span><span class="identifier">subject_phrase_term</span><span class="plain">, </span><span class="identifier">subject_phrase_prop</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] object NP: $0 such that: $D\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, &</span><span class="identifier">object_phrase_term</span><span class="plain">, </span><span class="identifier">object_phrase_prop</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_9"></a><b>§1.9. </b>The First Rule tells us that SP and OP are now each represented by
|
|
propositions with either no free variables, or just one, and then only if
|
|
the phrase refers to a single but vague thing.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">So far we have treated the subject and object exactly alike, running the
|
|
same computation on meaning lists generated by the same method. This is
|
|
the first point at which the placement as subject rather than object will
|
|
start to make a difference:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(i) we always bind a free variable in the object, but
|
|
</li><li>(ii) we only bind a free variable in the subject if we are looking at the
|
|
topmost verb in a whole sentence (i.e., for an SV rather than SN subtree).
|
|
</li></ul>
|
|
<p class="inwebparagraph">The SP is called the "subject phrase" because it contributes the subject of
|
|
a sentence: what it is a sentence about.
|
|
For instance, for an SV-subtree for "a woman is carrying an animal", we
|
|
produce φ_S = ∃ x: woman(x) and φ_O = ∃ x: animal(x).
|
|
But for an SN-subtree for "a woman carrying an animal" — which vaguely
|
|
describes something, in a way that can be tested for any given candidate x —
|
|
we produce φ_S = woman(x) with x remaining free.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Bind up any free variable in the OP and sometimes the SP, too</span> <span class="cwebmacronumber">1.9</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SV_not_SN</span><span class="plain">) </span><span class="identifier">subject_phrase_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::bind_existential</span><span class="plain">(</span><span class="identifier">subject_phrase_prop</span><span class="plain">, &</span><span class="identifier">subject_phrase_term</span><span class="plain">);</span>
|
|
<span class="identifier">object_phrase_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::bind_existential</span><span class="plain">(</span><span class="identifier">object_phrase_prop</span><span class="plain">, &</span><span class="identifier">object_phrase_term</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_10"></a><b>§1.10. </b>Of all the thousands of paragraphs of code in Inform, this is the one which
|
|
most sums up "how it works". We started with a sentence in
|
|
the source text, and have now extracted the following components of its
|
|
meaning: the subject phrase (SP) has become the term t_S subject to the
|
|
proposition φ_S being true; the object phrase (OP) is similarly now a
|
|
pair t_O such that φ_O. From the verb phrase (VP), we have found a
|
|
binary relation B, meant either in a positive sense (B does hold) or a
|
|
negative one (it doesn't). And now:
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Second Rule. The combined "meaning" Σ is as follows:
|
|
</p>
|
|
|
|
<ul class="items"><li>(1) if we are parsing a whole sentence (i.e., an SV-subtree), or φ_S is
|
|
not in the form Q x∈{ x|θ(x)}, then:
|
|
Σ = φ_S ∧ φ'_O ∧ B(t_S, t'_O)
|
|
if the sense is positive, or
|
|
φ_S ∧ ¬(φ'_O ∧ B(t_S, t'_O))
|
|
if not.
|
|
</li><li>(2) if we are parsing a relative clause (i.e., an SN-subtree), and φ_S is of the form
|
|
Q x∈{ x|θ(x)}, then:
|
|
Σ = Q x∈{ x|θ(x) ∧ φ'_O ∧ B(t_S, t'_O)}
|
|
if the sense is positive, or
|
|
Q x∈{ x|θ(x) ∧ ¬(φ'_O ∧ B(t_S, t'_O))
|
|
if not. Here φ'_O and t'_O are φ_O and t_O modified to relabel its
|
|
variables so that there are no accidental clashes with variables named in
|
|
φ_S.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP1_11"></a><b>§1.11. </b>That simple rule took the author a long, long time to work out,
|
|
so it may be worth a little discussion:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) The Second Rule is a generalisation of the way comparison operators like
|
|
<code class="display"><span class="extract">==</span></code> or <code class="display"><span class="extract">>=</span></code> work in conventional programming languages. For if
|
|
t_S and t_O are both constants, and φ_S and φ_O both
|
|
empty, we obtain just B(t_S, t_O) and ¬(B(t_S, t_O)). For instance,
|
|
"score is 10" becomes just is(<code class="display"><span class="extract">score</span></code>, 10), which compiles just to
|
|
<code class="display"><span class="extract">(score == 10)</span></code>.
|
|
</li><li>(b) In general, though, the meaning of an English sentence is not just that
|
|
the verb is true, but also that the subject and object make sense. For
|
|
"a woman is carrying an animal" to be true, there has to be such a woman,
|
|
and such an animal. This is the content of φ_S and φ_O. So the
|
|
formula above can be read as "the subject makes sense, and the object makes
|
|
sense, and they relate to each other in the way that the verb claims".
|
|
</li><li>(c) In the case of negation, it's important that we produce
|
|
φ_S ∧ ¬(φ'_O ∧ B(t_S, t_O)) rather than
|
|
φ_S∧φ'_O∧¬(B(t_S, t_O)). To see the difference, consider
|
|
the sentence "The box does not contain three coins". The first formula,
|
|
which is correct, means roughly "it's not true that there are three coins
|
|
x such that x is in the box", whereas the second, wrong, means
|
|
"three coins x exist such that x is not in the box".
|
|
</li><li>(d) The difference between cases (1) and (2) is actually very slight. Case (2)
|
|
arises only when a relative clause is qualifying the range of a collection
|
|
of things: for instance, in "every man who is in the Garden", we have
|
|
φ_S = ∀ x∈{ x| man(x)} and then need to
|
|
apply the relation in(x, <code class="display"><span class="extract">Garden</span></code>). If we used formula (1)
|
|
we would then have
|
|
Σ = ∀ x∈{ x| man(x)}: in(x, <code class="display"><span class="extract">Garden</span></code>)
|
|
which means "every man is in the Garden" — making a statement about
|
|
everything covered by φ_S, not restricting the coverage of φ_S,
|
|
as a relative clause should. Using formula (2), however, we get:
|
|
Σ = ∀ x∈{ x| man(x)∧ in(x, <code class="display"><span class="extract">Garden</span></code>)}
|
|
Note that these formulae are identical except for what we might call punctuation.
|
|
</li><li>(e) The modification needed to make φ'_O out of φ_O is pretty well
|
|
inconsequential. It makes no difference to the meaning of φ_O.
|
|
Consider the example "a woman is carrying an animal" once again.
|
|
t_S = x and φ_S = woman(x), which use x; and on the other
|
|
hand t_O = x and φ_O = animal(x), which also use x. Clearly
|
|
we don't mean the same x on both sides, so we relabel the OP to get y
|
|
such that animal(y). There is not really any asymmetry between the
|
|
SP and OP here, because it would have been just as good to relabel the SP.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP1_12"></a><b>§1.12. </b>Lemma. The result Σ of the Second Rule is a proposition containing
|
|
either 0 or 1 free variables; Σ has 1 free variable if and only if we
|
|
are converting an SN-subtree, and the subject phrase of the sentence describes
|
|
a single thing vaguely.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Proof. φ_O contains no free variables, since we bound it up above,
|
|
and the same must be true of its relabelled version φ'_O. If we have
|
|
an SV-subtree then φ_S similarly contains no free variables; we only
|
|
leave it unbound for an SN-subtree. In that case, the First Rule tells us that
|
|
it has a free variable if and only if the SP describes a single thing vaguely.
|
|
The only other content of Σ is the predicate B(t_S, t'_O), so extra
|
|
free variables can only appear if either t_S or t'_O contains a variable
|
|
not already seen in φ_S and φ'_O. But cases (b), (c) and (d) of
|
|
the First Rule make clear that in any pair (t, φ) arising from a noun
|
|
phrase, either t is a constant or else it is a variable appearing in φ.
|
|
So the terms of the final B predicate in Σ cannot add new free
|
|
variables, and the lemma is proved.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">By similar argument, if φ_S and φ_O are well-formed propositions
|
|
(syntactically valid and using variables either freely or within the scope
|
|
of quantification) then so is Σ.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_13"></a><b>§1.13. </b>Now to implement the Second Rule:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Combine the SP, VP and OP meanings into a single proposition for the sentence</span> <span class="cwebmacronumber">1.13</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">use_case_2</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">SV_not_SN</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">subject_phrase_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::remove_final_close_domain</span><span class="plain">(</span><span class="identifier">subject_phrase_prop</span><span class="plain">, &</span><span class="identifier">use_case_2</span><span class="plain">);</span>
|
|
|
|
<<span class="cwebmacro">Deal with the English irregularity concerning -where words</span> <span class="cwebmacronumber">1.13.1</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] Before renumbering of OP: t = $0, phi = $D\n"</span><span class="plain">, </span><span class="identifier">conv_log_depth</span><span class="plain">, &</span><span class="identifier">object_phrase_term</span><span class="plain">, </span><span class="identifier">object_phrase_prop</span><span class="plain">);</span>
|
|
<span class="identifier">object_phrase_term</span><span class="plain">.</span><span class="element">variable</span><span class="plain"> =</span>
|
|
<span class="functiontext">Calculus::Variables::renumber_bound</span><span class="plain">(</span><span class="identifier">object_phrase_prop</span><span class="plain">, </span><span class="identifier">subject_phrase_prop</span><span class="plain">, </span><span class="identifier">object_phrase_term</span><span class="plain">.</span><span class="element">variable</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">object_phrase_term</span><span class="plain">.</span><span class="element">variable</span><span class="plain"> >= </span><span class="constant">26</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad OP renumbering"</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] After renumbering of OP: t = $0, phi = $D\n"</span><span class="plain">, </span><span class="identifier">conv_log_depth</span><span class="plain">, &</span><span class="identifier">object_phrase_term</span><span class="plain">, </span><span class="identifier">object_phrase_prop</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="identifier">subject_phrase_prop</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_phrase_negated</span><span class="plain">)</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Atoms::new</span><span class="plain">(</span><span class="constant">NEGATION_OPEN_ATOM</span><span class="plain">));</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="identifier">object_phrase_prop</span><span class="plain">);</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">,</span>
|
|
<span class="functiontext">Calculus::Atoms::binary_PREDICATE_new</span><span class="plain">(</span><span class="identifier">verb_phrase_relation</span><span class="plain">, </span><span class="identifier">subject_phrase_term</span><span class="plain">, </span><span class="identifier">object_phrase_term</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_phrase_negated</span><span class="plain">)</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Atoms::new</span><span class="plain">(</span><span class="constant">NEGATION_CLOSE_ATOM</span><span class="plain">));</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_case_2</span><span class="plain">)</span>
|
|
<span class="identifier">sentence_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Atoms::new</span><span class="plain">(</span><span class="constant">DOMAIN_CLOSE_ATOM</span><span class="plain">));</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] Initial meaning: $D\n"</span><span class="plain">, </span><span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">sentence_prop</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_13_1"></a><b>§1.13.1. </b>The following provides for the fact that when one says "X is somewhere",
|
|
"X is anywhere", "X is nowhere", or "X is everywhere", one is talking about
|
|
the location of X and not X itself. Thus, "the keys are somewhere" means
|
|
that they have some location, not that they literally are a location. (This
|
|
is irregular because it differs from "something" and "someone".)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Deal with the English irregularity concerning -where words</span> <span class="cwebmacronumber">1.13.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">k_atom</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::composited_kind</span><span class="plain">(</span><span class="identifier">object_phrase_prop</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">k_atom</span><span class="plain">) && (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">k_atom</span><span class="plain">-></span><span class="element">assert_kind</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">verb_phrase_relation</span><span class="plain"> == </span><span class="identifier">R_equality</span><span class="plain">) && (</span><span class="identifier">room_containment_predicate</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Calculus::Atoms::set_composited</span><span class="plain">(</span><span class="identifier">k_atom</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="identifier">verb_phrase_relation</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_reversal</span><span class="plain">(</span><span class="identifier">room_containment_predicate</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] Decompositing object: $D\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">object_phrase_prop</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1_13">§1.13</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_14"></a><b>§1.14. Simplification. </b>Every proposition generated here, whether it arises as "there is/are" plus a
|
|
noun phrase or by the Second Rule, is simplified before being returned.
|
|
Because of the way the recursion is set up, this means that intermediate
|
|
propositions for relative clauses within a sentence are always simplified
|
|
before being used to build the whole sentence.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">What happens here is that we try a sequence of tactical moves to change
|
|
the proposition for the better — which usually means eliminating bound
|
|
variables, where we can: they are a bad thing because they compile to loops
|
|
which may be slow and awkward to construct.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Simplifications are allowed to change Σ — indeed that's the whole
|
|
idea — but not t_S, the term representing what the sentence talks about.
|
|
(Indeed, they aren't even shown what it is.) Moreover, a simplification can
|
|
only turn Σ to Σ' if:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(i) Σ' remains a syntactically correct proposition with well-formed
|
|
quantifiers,
|
|
</li><li>(ii) Σ' has the same number of free variables as Σ, and
|
|
</li><li>(iii) in all situations and for all possible values of any free variables,
|
|
Σ' is true if and only if Σ is.
|
|
</li></ul>
|
|
<p class="inwebparagraph">Rules (i) and (ii) are checked as we go, with internal errors thrown if ever
|
|
they should fail; the checking takes only a trivial amount of time, and I
|
|
generally agree with Tony Hoare's maxim that removing checks like this
|
|
in the program as shipped to users is like wearing a life-jacket while
|
|
learning to sail on dry land, and then taking it off when going to sea.
|
|
Still, rule (iii) can only be ensured by writing the routines carefully.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The simplification routines can all be found in "Simplifications".
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">proposition</span><span class="plain">, </span><span class="identifier">simp</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">changed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">NF</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::number_free</span><span class="plain">(</span><span class="identifier">proposition</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">proposition</span><span class="plain">) </span><span class="identifier">proposition</span><span class="plain"> = </span><span class="identifier">simp</span><span class="plain">(</span><span class="identifier">proposition</span><span class="plain">, &</span><span class="identifier">changed</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">changed</span><span class="plain">) </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] %s: $D\n"</span><span class="plain">, </span><span class="identifier">conv_log_depth</span><span class="plain">, #</span><span class="identifier">simp</span><span class="plain">, </span><span class="identifier">proposition</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Calculus::Variables::is_well_formed</span><span class="plain">(</span><span class="identifier">proposition</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">NF</span><span class="plain"> != </span><span class="functiontext">Calculus::Variables::number_free</span><span class="plain">(</span><span class="identifier">proposition</span><span class="plain">))) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Failed after applying %s: $D"</span><span class="plain">, #</span><span class="identifier">simp</span><span class="plain">, </span><span class="identifier">proposition</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(#</span><span class="identifier">simp</span><span class="plain"> </span><span class="string">" simplified proposition into one which is not well-formed"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Simplify the resultant proposition</span> <span class="cwebmacronumber">1.14</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::is_well_formed</span><span class="plain">(</span><span class="identifier">sentence_prop</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">"Failed before simplification: $D"</span><span class="plain">, </span><span class="identifier">sentence_prop</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to simplify proposition which is not well-formed"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::nothing_constant</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::use_listed_in</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::negated_determiners_nonex</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::negated_satisfiable</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::make_kinds_of_value_explicit</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::redundant_kinds</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::turn_right_way_round</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::region_containment</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::everywhere_and_nowhere</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::reduce_predicates</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::eliminate_redundant_variables</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::not_related_to_something</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::convert_gerunds</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::eliminate_to_have</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::is_all_rooms</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::redundant_kinds</span><span class="plain">);</span>
|
|
|
|
<span class="functiontext">Calculus::Variables::renumber</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">); </span><span class="comment">just for the sake of tidiness</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b></p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Calculus::Propositions::FromSentences::simplify</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">sentence_prop</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">conv_log_depth</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::nothing_constant</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::use_listed_in</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::negated_determiners_nonex</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::negated_satisfiable</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::make_kinds_of_value_explicit</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::redundant_kinds</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::turn_right_way_round</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::region_containment</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::everywhere_and_nowhere</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::reduce_predicates</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::eliminate_redundant_variables</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::not_related_to_something</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::convert_gerunds</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::eliminate_to_have</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::is_all_rooms</span><span class="plain">);</span>
|
|
<span class="identifier">APPLY_SIMPLIFICATION</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Simplifications::redundant_kinds</span><span class="plain">);</span>
|
|
|
|
<span class="functiontext">Calculus::Variables::renumber</span><span class="plain">(</span><span class="identifier">sentence_prop</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">); </span><span class="comment">just for the sake of tidiness</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sentence_prop</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Propositions::FromSentences::simplify appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. The meaning of a noun phrase. </b>The First Rule tells us to translate a noun phrase (NP) into a pair of a term t
|
|
and a proposition φ. We read this as "t such that φ is true".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">For reasons explained below, a small amount of context is supplied: if the
|
|
term will need to have a particular kind of value, then that kind is given
|
|
to us. (But if it only needs to be an object, or if we don't know anything
|
|
about its kind, the <code class="display"><span class="extract">K</span></code> argument will be <code class="display"><span class="extract">NULL</span></code>.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">As can be seen, an NP subtree consists either of an SN subtree representing
|
|
two further NPs joined by a verb to make a relative clause, or one of
|
|
three basic noun phrases: a value, a description, or a marker for an implied
|
|
but missing noun.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Calculus::Propositions::FromSentences::NP_subtree_to_proposition</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">subject_of_NP</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">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">NP_prop</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">W</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Tell the debugging log about the NP-subtree</span> <span class="cwebmacronumber">3.1</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">st</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject_term</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">st</span><span class="plain">) {</span>
|
|
<span class="plain">*</span><span class="identifier">subject_of_NP</span><span class="plain"> = *</span><span class="identifier">st</span><span class="plain">;</span>
|
|
<span class="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::copy</span><span class="plain">(</span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">p</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_like</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)) </span><<span class="cwebmacro">This NP was parsed as a description</span> <span class="cwebmacronumber">3.4</span>>
|
|
<span class="reserved">else</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="constant">UNKNOWN_NT</span><span class="plain">) </span><<span class="cwebmacro">This NP is only a ghostly presence</span> <span class="cwebmacronumber">3.5</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">This NP was parsed as a value</span> <span class="cwebmacronumber">3.3</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<<span class="cwebmacro">If we have a single adjective which could also be a noun, and a value is required, convert it to a noun</span> <span class="cwebmacronumber">3.6</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">If we have a constant qualified by a substantive proposition, rewrite in terms of variable</span> <span class="cwebmacronumber">3.7</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Close any open domain group</span> <span class="cwebmacronumber">3.8</span>><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Verify that the output satisfies the First Rule, throwing internal errors if not</span> <span class="cwebmacronumber">3.2</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NP_prop</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Calculus::Propositions::FromSentences::NP_subtree_to_proposition is used in <a href="#SP1_8">§1.8</a>, <a href="#SP3_1">§3.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1"></a><b>§3.1. </b>Just as for SV-subtrees, we tell the debugging log at the start...
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Tell the debugging log about the NP-subtree</span> <span class="cwebmacronumber">3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">++;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] Starting Calculus::Propositions::FromSentences::NP_subtree_to_proposition on: <%W>\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2"></a><b>§3.2. </b>...and also at the end.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Verify that the output satisfies the First Rule, throwing internal errors if not</span> <span class="cwebmacronumber">3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::is_well_formed</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed NP proposition"</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NF</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::number_free</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NF</span><span class="plain"> >= </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"two or more free variables from NP"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subject_of_NP</span><span class="plain">-></span><span class="element">constant</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NP_prop</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"constant plus substantive prop from NP"</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="identifier">NF</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">v</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::variable_underlying</span><span class="plain">(</span><span class="identifier">subject_of_NP</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Variables::status</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">, </span><span class="identifier">v</span><span class="plain">) != </span><span class="constant">FREE_VST</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"free variable from NP but not the preferred term"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">, </span><span class="string">"[%d] Calculus::Propositions::FromSentences::NP_subtree_to_proposition: %W --> t = $0, phi = $D\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">subject_of_NP</span><span class="plain">, </span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">--;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3"></a><b>§3.3. </b>Here we find a constant C and return t=C with a null φ, except
|
|
in one case: where C is the name of an either/or property, such as
|
|
"closed". In the context of a value, this is a noun — it identifies
|
|
which property we are talking about — and this is why
|
|
<code class="display"><span class="extract">ExParser::Conversion::VAL_subtree_to_spec</span></code> returns it as a constant. But inside a sentence, it
|
|
has to be considered an adjective, so rather than returning t = <code class="display"><span class="extract">closed</span></code>,
|
|
φ = T, we return t=x and φ = closed(x). If we didn't do
|
|
this, text like "the trapdoor is closed" would translate to the
|
|
proposition is(<code class="display"><span class="extract">trapdoor</span></code>, <code class="display"><span class="extract">closed</span></code>), which would then fail in
|
|
type-checking.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">(Note that this is a different sort of noun/adjective ambiguity than the
|
|
one arising below, which is to do with enumerated value properties.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">This NP was parsed as a value</span> <span class="cwebmacronumber">3.3</span>> =
|
|
</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">p</span><span class="plain">;</span>
|
|
<span class="plain">*</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_constant</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">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="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_property</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">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) {</span>
|
|
<span class="plain">*</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(0);</span>
|
|
<span class="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::unary_PREDICATE_from_aph</span><span class="plain">(</span><span class="functiontext">Properties::EitherOr::get_aph</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">), </span><span class="identifier">FALSE</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">Properties::Valued::coincides_with_kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) {</span>
|
|
<span class="plain">*</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(0);</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</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="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::KIND_new</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(0));</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4"></a><b>§3.4. </b>If <code class="display"><span class="extract">Calculus::Propositions::from_spec</span></code> is given a constant value C then it returns the
|
|
proposition is(x, C): we look out for this and translate it to
|
|
t=C, φ = T. Otherwise, φ can be exactly the proposition returned,
|
|
and the first term occurring in it will be chosen as the subject t. (In
|
|
particular, if φ opens with a quantifier then t will be the variable
|
|
it binds.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">This NP was parsed as a description</span> <span class="cwebmacronumber">3.4</span>> =
|
|
</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">p</span><span class="plain">;</span>
|
|
<span class="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::copy</span><span class="plain">(</span><span class="functiontext">Calculus::Propositions::from_spec</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">Calculus::Propositions::match</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">, </span><span class="constant">2</span><span class="plain">, </span><span class="constant">PREDICATE_ATOM</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">END_PROP_HERE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">)) {</span>
|
|
<span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::is_x_equals</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">) { *</span><span class="identifier">subject_of_NP</span><span class="plain"> = *</span><span class="identifier">pt</span><span class="plain">; </span><span class="identifier">NP_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; }</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Calculus::Propositions::match</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">, </span><span class="constant">2</span><span class="plain">, </span><span class="constant">KIND_ATOM</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">END_PROP_HERE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">)) &&</span>
|
|
<span class="plain">(<</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">formal</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">-</span><span class="identifier">variable</span><span class="plain">-</span><span class="identifier">singular</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">))) {</span>
|
|
<span class="functiontext">Calculus::Atoms::set_unarticled</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NP_prop</span><span class="plain">) *</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::get_first_cited_term</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5"></a><b>§3.5. </b>When Inform reads a condition so abbreviated that both the subject and
|
|
the verb have been left out, it assumes the verb is "to be" and that the
|
|
subject will be whatever is being worked on. For instance,
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if an unlocked container, ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">is read as the verb phrase "is" with <code class="display"><span class="extract">ABSENT_SUBJECT_NT</span></code> as SP
|
|
and "an unlocked container" as OP.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">ABSENT_SUBJECT_NT</span></code> nodes are easy to deal with since they translate to the I6
|
|
variable <code class="display"><span class="extract">self</span></code> in the final compiled code; the <code class="display"><span class="extract">Rvalues::new_self_object_constant</span></code> routine
|
|
returns a specification which refers to this. From a predicate
|
|
calculus point of view, this is just another constant.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">This NP is only a ghostly presence</span> <span class="cwebmacronumber">3.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="functiontext">Rvalues::new_self_object_constant</span><span class="plain">());</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_6"></a><b>§3.6. </b>Suppose we have a situation like this:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Texture is a kind of value. Rough, smooth and jagged are textures. A thing has a texture.</p>
|
|
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<p>Feeling relates various rooms to one texture. The verb to feel (he feels) implies the feeling relation.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">and consider the sentences:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>[1] the broken bottle is jagged [2] the Spiky Cavern feels jagged</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">Now suppose we are working on the NP "jagged". In (1), it's an adjective: we
|
|
are talking about a quality of the bottle. But in (2), it's a noun: we are
|
|
establishing a relation between two values, the Cavern and the jagged texture.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Up to this point, "jagged" will have produced t=x, φ=jagged(x)
|
|
in both cases — the adjectival reading of the word. The way we can tell if we
|
|
are in case (2) is if a value of a specific kind (and not an object) is
|
|
expected as the outcome. In the case of the equality relation used in (1),
|
|
"is", the terms can be anything; but in the case of the feeling relation
|
|
used in (2), the second term, corresponding to the noun phrase "jagged" in
|
|
this sentence, has to have the kind of value "texture". So we convert it
|
|
into noun form, and return t=<code class="display"><span class="extract">texture</span></code>, φ = T.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">(Note that this is a different sort of noun/adjective ambiguity than the
|
|
one arising above, which is to do with either/or properties.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Another case which can occur is:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>the bottle provides the property closed</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">where the presence of the words "the property" needs to alert us that
|
|
"closed" is a noun referring to the property itself, not to a nameless
|
|
object possessing that property. When the S-parser matches a property in
|
|
that way, it assigns a score value of <code class="display"><span class="extract">TRUE</span></code> to the relevant ML entry to
|
|
show this. (Score values otherwise aren't used for property names.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">If we have a single adjective which could also be a noun, and a value is required, convert it to a noun</span> <span class="cwebmacronumber">3.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (((</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">CON_property</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">property_name_used_as_noun_ANNOT</span><span class="plain">))) || (</span><span class="identifier">K</span><span class="plain">)) {</span>
|
|
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pct</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::convert_adj_to_noun</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pct</span><span class="plain">.</span><span class="element">constant</span><span class="plain">) { *</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="identifier">pct</span><span class="plain">; </span><span class="identifier">NP_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; }</span>
|
|
<span class="plain">}</span>
|
|
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_7"></a><b>§3.7. </b>If we have so far produced a constant term t = C and a non-null proposition
|
|
φ, then we convert t to a new free variable, say t = y, we then bind
|
|
any free variable in the old φ and then change to ∃ y: is(y, C)∧φ.
|
|
For instance, if we are working on the OP "the box in a room" from this:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>a thing in the box in a room</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">then the constant is C = <code class="display"><span class="extract">box</span></code>, and Sstp returned
|
|
φ = ∃ x: room(x)∧is(x, <code class="display"><span class="extract">ContainerOf(box)</span></code>).
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">If we have a constant qualified by a substantive proposition, rewrite in terms of variable</span> <span class="cwebmacronumber">3.7</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">subject_of_NP</span><span class="plain">-></span><span class="element">constant</span><span class="plain">) && (</span><span class="identifier">NP_prop</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">y</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::find_unused</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">,</span>
|
|
<span class="string">"[%d] Rewriting qualified constant t = $0 (new var %d)\n"</span><span class="plain">, </span><span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">subject_of_NP</span><span class="plain">, </span><span class="identifier">y</span><span class="plain">);</span>
|
|
<span class="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span>
|
|
<span class="functiontext">Calculus::Atoms::binary_PREDICATE_new</span><span class="plain">(</span><span class="identifier">R_equality</span><span class="plain">, *</span><span class="identifier">subject_of_NP</span><span class="plain">, </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(</span><span class="identifier">y</span><span class="plain">)),</span>
|
|
<span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="plain">*</span><span class="identifier">subject_of_NP</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_variable</span><span class="plain">(</span><span class="identifier">y</span><span class="plain">);</span>
|
|
<span class="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Variables::bind_existential</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">, </span><span class="identifier">subject_of_NP</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PREDICATE_CALCULUS</span><span class="plain">,</span>
|
|
<span class="string">"[%d] Rewriting qualified constant: <%W> --> t = $0, phi = $D\n"</span><span class="plain">,</span>
|
|
<span class="identifier">conv_log_depth</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">subject_of_NP</span><span class="plain">, </span><span class="identifier">NP_prop</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_8"></a><b>§3.8. </b>If the NP was something like "at least four open doors", we will so far
|
|
have built <code class="display"><span class="extract">QUANTIFIER --> DOMAIN_OPEN --> KIND --> PREDICATE</span></code>, and now that
|
|
we have reached the end of the noun phrase we need to add a <code class="display"><span class="extract">DOMAIN_CLOSE</span></code>
|
|
atom. The following is written in a way that guarantees all such open groups
|
|
are closed, but in fact there should only ever be one open, so <code class="display"><span class="extract">nq</span></code> should
|
|
always evaluate to 0 or 1.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Close any open domain group</span> <span class="cwebmacronumber">3.8</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">nq</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">NP_prop</span><span class="plain">)</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-></span><span class="identifier">element</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">DOMAIN_OPEN_ATOM:</span><span class="plain"> </span><span class="identifier">nq</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="identifier">DOMAIN_CLOSE_ATOM:</span><span class="plain"> </span><span class="identifier">nq</span><span class="plain">--; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nq</span><span class="plain"> < </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed proposition with too many domain ends"</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">i</span><span class="plain"><=</span><span class="identifier">nq</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="identifier">NP_prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::concatenate</span><span class="plain">(</span><span class="identifier">NP_prop</span><span class="plain">, </span><span class="functiontext">Calculus::Atoms::new</span><span class="plain">(</span><span class="constant">DOMAIN_CLOSE_ATOM</span><span class="plain">));</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="11-tc.html">Back to 'Tree Conversions'</a></li><li><a href="11-sm.html">Continue with 'Simplifications'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|