mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
567 lines
60 KiB
HTML
567 lines
60 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>9/rk</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<!--Weave of '9/ass' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">core</a></li><li><a href="index.html#9">Chapter 9: The A-Parser</a></li><li><b>Assemblies</b></li></ul><p class="purpose">To build the complex multi-object assemblies which result from allowing the source text to say things like "in every room is a vehicle".</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP6">§6. Initialisation</a></li><li><a href="#SP9">§9. New generalisations</a></li><li><a href="#SP11">§11. The assembly process</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>Assemblies are made when an object of a given kind is created, and when
|
|
generalisations about that kind mean that further creations are also
|
|
needed. For instance: if a generalisation has said that every container
|
|
contains a shoe, then each time a container is created, we also need to
|
|
create a shoe, and assert a spatial relationship between them.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In practice we do this by a simple process which involves cutting and
|
|
pasting of subtrees of the parse tree, which motivates the following
|
|
data structure.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Generalisations are essentially fragments of parse tree stored for later use.
|
|
They handle sentences like
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>In every container is a coin.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">which are done by recognising the prototype part ("in every container") in
|
|
the parse tree and grafting on a duplicate of the assembly part ("a coin")
|
|
in place of the <code class="display"><span class="extract">EVERY_NT</span></code> subtree ("every container"). Sometimes the EVERY
|
|
subtree is the whole prototype subtree ("Every coin is on a table"), in
|
|
which case <code class="display"><span class="extract">px</span></code> and <code class="display"><span class="extract">substitute_at</span></code> in the following structure coincide.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Each kind (in this example "container") keeps a linked list of the
|
|
generalisations which apply to it.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">generalisation</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">look_for</span><span class="plain">; </span> <span class="comment">prototype situation to look for</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">what_to_make</span><span class="plain">; </span> <span class="comment">subtree for what to assemble</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">substitute_at</span><span class="plain">; </span> <span class="comment">position under <code class="display"><span class="extract">look_for</span></code> of the EVERY node</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">next</span><span class="plain">; </span> <span class="comment">next in list of generalisations about kind</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">generalisation</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure generalisation is accessed in 3/pd, 5/lp, 5/ut, 5/un, 5/ins, 6/rlt, 6/nv, 7/ss, 7/hdn, 7/ns, 7/oaf, 7/rs, 8/ie, 8/ec, 8/ed, 9/tfa, 9/tbath, 9/rpt, 9/tc, 9/ma, 9/rk, 9/imp, 9/pd, 10/teav, 10/cap, 11/ap, 11/pr, 11/bas, 11/tc, 11/sm, 12/dtd, 12/cdp, 14/rv, 14/lv, 14/cn, 14/ds, 14/ds2, 15/cp, 16/is, 16/in, 19/tb, 19/rsft, 19/tod, 20/eq, 21/rl, 21/rl2, 21/fao, 21/rps, 21/sv, 21/ac, 22/ph, 22/tp, 22/tp2, 23/ad, 24/lv, 24/sf, 25/in, 25/pi, 25/cii, 25/cp, 26/uo, 26/tti, 26/pc, 26/ts, 27/cm and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>For reasons to do with timing, each object needs to keep track of which
|
|
generalisations have and have not yet applied to it. In practice, this is
|
|
a list of pairs (K, g) where K is a kind and g is the most recent one
|
|
applied from K's list.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">application</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">generalisation_owner</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">latest_applied</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">application</span><span class="plain"> *</span><span class="identifier">next</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">application</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure application is accessed in 3/pd, 5/lp, 5/ut, 5/un, 5/ins, 6/rlt, 6/nv, 7/ss, 7/hdn, 7/ns, 7/oaf, 7/rs, 8/ie, 8/ec, 8/ed, 9/tfa, 9/tbath, 9/rpt, 9/tc, 9/ma, 9/rk, 9/imp, 9/pd, 10/teav, 10/cap, 11/ap, 11/pr, 11/bas, 11/tc, 11/sm, 12/dtd, 12/cdp, 14/rv, 14/lv, 14/cn, 14/ds, 14/ds2, 15/cp, 16/is, 16/in, 19/tb, 19/rsft, 19/tod, 20/eq, 21/rl, 21/rl2, 21/fao, 21/rps, 21/sv, 21/ac, 22/ph, 22/tp, 22/tp2, 23/ad, 24/lv, 24/sf, 25/in, 25/pi, 25/cii, 25/cp, 26/uo, 26/tti, 26/pc, 26/ts, 27/cm and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>These structures are combined in the following packet of data attached to
|
|
each inference subject:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">assemblies_data</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">generalisation_list</span><span class="plain">; </span> <span class="comment">kinds only: assembly instructions, if any</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">application</span><span class="plain"> *</span><span class="identifier">applications_so_far</span><span class="plain">; </span> <span class="comment">instances only: progress</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">named_after</span><span class="plain">; </span> <span class="comment">name derived from another: e.g. "Jane's nose"</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">named_after_text</span><span class="plain">; </span> <span class="comment">text of the derived part, e.g. "nose"</span>
|
|
<span class="plain">} </span><span class="reserved">assemblies_data</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure assemblies_data is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. Initialisation. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::initialise_assemblies_data</span><span class="plain">(</span><span class="reserved">assemblies_data</span><span class="plain"> *</span><span class="identifier">ad</span><span class="plain">) {</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>generalisation_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>applications_so_far</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>named_after</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>named_after_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::initialise_assemblies_data is used in 16/is (<a href="16-is.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>Setting the naming-after information.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::name_object_after</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">after</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="reserved">assemblies_data</span><span class="plain"> *</span><span class="identifier">ad</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>named_after</span><span class="plain"> = </span><span class="identifier">after</span><span class="plain">;</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>named_after_text</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::name_object_after is used in 9/tc (<a href="9-tc.html#SP8_4_1">§8.4.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>And reading it again.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">Assertions::Assemblies::what_this_is_named_after</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
|
|
<span class="reserved">assemblies_data</span><span class="plain"> *</span><span class="identifier">ad</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ad</span><span class="plain">-</span><span class="element">>named_after</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::get_named_after_text</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
|
|
<span class="reserved">assemblies_data</span><span class="plain"> *</span><span class="identifier">ad</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ad</span><span class="plain">-</span><span class="element">>named_after_text</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::what_this_is_named_after appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::get_named_after_text appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. New generalisations. </b>Here a new generalisation is made. The <code class="display"><span class="extract">look_for</span></code> subtree contains the
|
|
<code class="display"><span class="extract">EVERY_NT</span></code> node, but it might be either at the top, as here:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Every container is in the Lumber Room.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">or the first child of a <code class="display"><span class="extract">RELATIONSHIP_NT</span></code> node, as here:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>In every container is a vehicle.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">In the second case the <code class="display"><span class="extract">what_to_make</span></code> subtree is an <code class="display"><span class="extract">COMMON_NOUN_NT</span></code>, and in the
|
|
first it's a <code class="display"><span class="extract">RELATIONSHIP_NT</span></code> subtree.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::make_generalisation</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">look_for</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">what_to_make</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">EVERY_node</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">look_for</span><span class="plain">) == </span><span class="constant">EVERY_NT</span><span class="plain">) </span><span class="identifier">EVERY_node</span><span class="plain"> = </span><span class="identifier">look_for</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">look_for</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) && (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">look_for</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) == </span><span class="constant">EVERY_NT</span><span class="plain">))</span>
|
|
<span class="identifier">EVERY_node</span><span class="plain"> = </span><span class="identifier">look_for</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Generalisation without EVERY node"</span><span class="plain">);</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">EVERY_node</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Malformed EVERY node"</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Assertions::Assemblies::subtree_mentions_kind</span><span class="plain">(</span><span class="identifier">look_for</span><span class="plain">,</span><span class="identifier">k</span><span class="plain">,0)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Assertions::Assemblies::subtree_mentions_kind</span><span class="plain">(</span><span class="identifier">what_to_make</span><span class="plain">,</span><span class="identifier">k</span><span class="plain">,0)))</span>
|
|
<<span class="cwebmacro">Issue an infinite regress of assemblies problem message</span> <span class="cwebmacronumber">9.5</span>><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Forbid generalisation about fixed kinds</span> <span class="cwebmacronumber">9.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Forbid generalisation on both sides</span> <span class="cwebmacronumber">9.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">If we have to make a kind qualified by adjectives, expand that into a suitable subtree</span> <span class="cwebmacronumber">9.3</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">EVERY_node</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">g</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">generalisation</span><span class="plain">);</span>
|
|
<span class="identifier">g</span><span class="plain">-</span><span class="element">>look_for</span><span class="plain"> = </span><span class="identifier">look_for</span><span class="plain">;</span>
|
|
<span class="identifier">g</span><span class="plain">-</span><span class="element">>what_to_make</span><span class="plain"> = </span><span class="identifier">what_to_make</span><span class="plain">;</span>
|
|
<span class="identifier">g</span><span class="plain">-</span><span class="element">>substitute_at</span><span class="plain"> = </span><span class="identifier">EVERY_node</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Add this new generalisation to the list for the kind it applies to</span> <span class="cwebmacronumber">9.4</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="constant">you_can_ignore_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSEMBLIES</span><span class="plain">, </span><span class="string">"New generalisation made concerning $j:\</span><span class="plain">n</span><span class="string">Look for: $T\</span><span class="plain">n</span><span class="string">Make: $T\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">k</span><span class="plain">, </span><span class="identifier">g</span><span class="plain">-</span><span class="element">>look_for</span><span class="plain">, </span><span class="identifier">g</span><span class="plain">-</span><span class="element">>what_to_make</span><span class="plain">);</span>
|
|
|
|
<span class="functiontext">Assertions::Assemblies::ensure_all_generalisations_made</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::make_generalisation is used in 9/ma (<a href="9-ma.html#SP3_3_31">§3.3.31</a>, <a href="9-ma.html#SP3_3_34_1">§3.3.34.1</a>, <a href="9-ma.html#SP3_3_35">§3.3.35</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_1"></a><b>§9.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Forbid generalisation about fixed kinds</span> <span class="cwebmacronumber">9.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">instance_kind</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_nonobject_kind</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">instance_kind</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">instance_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Behaviour::has_named_constant_values</span><span class="plain">(</span><span class="identifier">instance_kind</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">look_for</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">what_to_make</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_AssemblyOnFixedKind</span><span class="plain">),</span>
|
|
<span class="string">"this generalisation can't be made"</span><span class="plain">,</span>
|
|
<span class="string">"because I only use generalisations to talk about values which can be "</span>
|
|
<span class="string">"created as needed, like things or scenes - not about those always "</span>
|
|
<span class="string">"existing in fixed ranges, like numbers or times."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_2"></a><b>§9.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Forbid generalisation on both sides</span> <span class="cwebmacronumber">9.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">what_to_make</span><span class="plain">) && (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">what_to_make</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) == </span><span class="constant">EVERY_NT</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">look_for</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">what_to_make</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_AssemblyOnBothSides</span><span class="plain">),</span>
|
|
<span class="string">"this generalisation can't be made"</span><span class="plain">,</span>
|
|
<span class="string">"because it uses 'every' or some similar generalisation on both sides, "</span>
|
|
<span class="string">"which is too rich for my taste."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_3"></a><b>§9.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">If we have to make a kind qualified by adjectives, expand that into a suitable subtree</span> <span class="cwebmacronumber">9.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">what_to_make</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">val</span><span class="plain">) && (</span><span class="functiontext">Descriptions::is_adjectives_plus_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">))) {</span>
|
|
<span class="functiontext">Assertions::Refiner::refine_from_simple_description</span><span class="plain">(</span><span class="identifier">what_to_make</span><span class="plain">, </span><span class="identifier">ParseTree::duplicate</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_4"></a><b>§9.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Add this new generalisation to the list for the kind it applies to</span> <span class="cwebmacronumber">9.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">assemblies_data</span><span class="plain"> *</span><span class="identifier">ad</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ad</span><span class="plain">-</span><span class="element">>generalisation_list</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="identifier">ad</span><span class="plain">-</span><span class="element">>generalisation_list</span><span class="plain"> = </span><span class="identifier">g</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">g2</span><span class="plain"> = </span><span class="identifier">ad</span><span class="plain">-</span><span class="element">>generalisation_list</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">g2</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) </span><span class="identifier">g2</span><span class="plain"> = </span><span class="identifier">g2</span><span class="plain">-</span><span class="element">>next</span><span class="plain">;</span>
|
|
<span class="identifier">g2</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">g</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">g</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_5"></a><b>§9.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue an infinite regress of assemblies problem message</span> <span class="cwebmacronumber">9.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Generalisation:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">look_for</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T"</span><span class="plain">, </span><span class="identifier">what_to_make</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_AssemblyRegress</span><span class="plain">),</span>
|
|
<span class="string">"this generalisation would be too dangerous"</span><span class="plain">,</span>
|
|
<span class="string">"because it would lead to infinite regress in the assembly process. Sometimes "</span>
|
|
<span class="string">"this happens if you have set up matters with text like 'A container is in every "</span>
|
|
<span class="string">"container.'."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>This is used only in checking for infinite regress:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::subtree_mentions_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">subtree</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">level</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">subtree</span><span class="plain">) == </span><span class="constant">COMMON_NOUN_NT</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">subtree</span><span class="plain">) == </span><span class="identifier">k</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">subtree</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) && (</span><span class="functiontext">Assertions::Assemblies::subtree_mentions_kind</span><span class="plain">(</span><span class="identifier">subtree</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">level</span><span class="plain">+1)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">level</span><span class="plain">>0) && (</span><span class="identifier">subtree</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) && (</span><span class="functiontext">Assertions::Assemblies::subtree_mentions_kind</span><span class="plain">(</span><span class="identifier">subtree</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">level</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::subtree_mentions_kind is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. The assembly process. </b>As noticed above, it's useful to have a routine which brings up to date the
|
|
application of generalisations. When this routine completes, every object
|
|
of a given kind has undergone every generalisation applicable to it exactly once.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::ensure_all_generalisations_made</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">) {</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">InferenceSubjects::is_within</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">)) && (</span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">))</span>
|
|
<span class="functiontext">Assertions::Assemblies::satisfies_generalisations</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::ensure_all_generalisations_made is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>Clearly one reason we might need to bring generalisations up to date is if
|
|
the kind of an object is determined, because that potentially expands the set of
|
|
generalisations applicable to it. But it's needlessly slow to apply a full
|
|
refresh when we know the only object which can be affected, so in that
|
|
situation we call just <code class="display"><span class="extract">Assertions::Assemblies::satisfies_generalisations</span></code> on the object in question.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::satisfies_generalisations</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">); </span><span class="identifier">k</span><span class="plain">; </span><span class="identifier">k</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">)) {</span>
|
|
<span class="reserved">application</span><span class="plain"> *</span><span class="identifier">app</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">app</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)-</span><span class="element">>applications_so_far</span><span class="plain">; </span><span class="identifier">app</span><span class="plain">; </span><span class="identifier">app</span><span class="plain"> = </span><span class="identifier">app</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">app</span><span class="plain">-</span><span class="element">>generalisation_owner</span><span class="plain"> == </span><span class="identifier">k</span><span class="plain">)</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Apply generalisations about K which have not yet been applied</span> <span class="cwebmacronumber">12.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::satisfies_generalisations is used in <a href="#SP11">§11</a>, 5/ins (<a href="5-ins.html#SP6">§6</a>, <a href="5-ins.html#SP19">§19</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_1"></a><b>§12.1. </b>At this point <code class="display"><span class="extract">app</span></code> points to the record of which generalisations in K
|
|
have been applied to the object so far, or is <code class="display"><span class="extract">NULL</span></code> if none of K's
|
|
generalisation has ever been applied to it.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Apply generalisations about K which have not yet been applied</span> <span class="cwebmacronumber">12.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">ignore_up_to</span><span class="plain"> = (</span><span class="identifier">app</span><span class="plain">)?(</span><span class="identifier">app</span><span class="plain">-</span><span class="element">>latest_applied</span><span class="plain">):</span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">g</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">g</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">)-</span><span class="element">>generalisation_list</span><span class="plain">; </span><span class="identifier">g</span><span class="plain">; </span><span class="identifier">g</span><span class="plain">=</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ignore_up_to</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">g</span><span class="plain"> == </span><span class="identifier">ignore_up_to</span><span class="plain">) </span><span class="identifier">ignore_up_to</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">app</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><<span class="cwebmacro">Create a new record for this previously unapplied kind</span> <span class="cwebmacronumber">12.1.1</span>><span class="plain">;</span>
|
|
<span class="identifier">app</span><span class="plain">-</span><span class="element">>latest_applied</span><span class="plain"> = </span><span class="identifier">g</span><span class="plain">;</span>
|
|
<span class="functiontext">Assertions::Assemblies::satisfies_generalisation</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">g</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_1_1"></a><b>§12.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Create a new record for this previously unapplied kind</span> <span class="cwebmacronumber">12.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">app</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">application</span><span class="plain">);</span>
|
|
<span class="identifier">app</span><span class="plain">-</span><span class="element">>generalisation_owner</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">app</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)-</span><span class="element">>applications_so_far</span><span class="plain">;</span>
|
|
<span class="functiontext">InferenceSubjects::get_assemblies_data</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)-</span><span class="element">>applications_so_far</span><span class="plain"> = </span><span class="identifier">app</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12_1">§12.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>It's worth a brief pause to think about the time and storage needed by the
|
|
above. Let N be the number of objects, and H the maximum depth of the kinds
|
|
hierarchy; while in theory H might be O(N), it's more likely to be about
|
|
log_2 N if the kinds hierarchy is balanced, and in practice even for very
|
|
large Inform source texts H is never larger than 7 or 8.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The storage required to record G generalisations is proportional to G,
|
|
since each appears only in a single linked list and is recorded in a single
|
|
structure instance. We clearly won't do better than that.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The storage required to record which generalisations have so far applied to
|
|
which objects is O(HN), since each object stores about 12H bytes of data,
|
|
which is significantly better than a bitmap recording all pairs of generalisations
|
|
and objects (which would be O(GN)). The running time of <code class="display"><span class="extract">Assertions::Assemblies::satisfies_generalisations</span></code>
|
|
applied to object X is O(G_X H^2), where G_X is the number of generalisations
|
|
which can be applied to X. In the course of compilation this is called once
|
|
each time the kind of X is changed — at most H times — and once each time
|
|
a new generalisation applicable to X is added — at most G_X times. So we
|
|
have a total time consumption of O(G_X^2 H^2 + G_X H^3). In practice the
|
|
constants are low, G_X is very small compared to the size of the source
|
|
text, and so is H.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The main point, then, is that the mechanism above is much, much faster than
|
|
repeatedly checking each generalisation against each object, for a cost of
|
|
O(G^2N).
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>So here we get on with the actual construction: we apply <code class="display"><span class="extract">g</span></code> to <code class="display"><span class="extract">infs</span></code>. What
|
|
we actually do is to insert new sentences after the current one.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">implicit_recursion_exception</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">thrown when we've gone into infinite regress</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Assemblies::satisfies_generalisation</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">generalisation</span><span class="plain"> *</span><span class="identifier">g</span><span class="plain">) {</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">counterpart</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">snatcher</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Plugins::Call::detect_bodysnatching</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, &</span><span class="identifier">snatcher</span><span class="plain">, &</span><span class="identifier">counterpart</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSEMBLIES</span><span class="plain">, </span><span class="string">"Body-snatcher found! Subj $j, snatcher %d, counterpart $j\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">infs</span><span class="plain">, </span><span class="identifier">snatcher</span><span class="plain">, </span><span class="identifier">counterpart</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">snatcher</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs_k</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>substitute_at</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Throw the infinite regress exception if the current sentence makes too many things</span> <span class="cwebmacronumber">14.1</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">new_sentence</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">SENTENCE_NT</span><span class="plain">);</span>
|
|
|
|
<span class="comment">mark this sentence as implicit, and increase its generation count:</span>
|
|
<span class="identifier">ParseTree::set_implicit_in_creation_of</span><span class="plain">(</span><span class="identifier">new_sentence</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">new_sentence</span><span class="plain">, </span><span class="constant">implicitness_count_ANNOT</span><span class="plain">,</span>
|
|
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="constant">implicitness_count_ANNOT</span><span class="plain">) + 1);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">new_sentence</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">));</span>
|
|
|
|
<span class="comment">temporarily make the <code class="display"><span class="extract">EVERY_NT</span></code> node refer to the specific new <code class="display"><span class="extract">infs</span></code>:</span>
|
|
<span class="functiontext">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>substitute_at</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">);</span>
|
|
|
|
<span class="comment">make the new sentence an assertion:</span>
|
|
<span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">AVERB_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">, </span><span class="constant">ASSERT_VB</span><span class="plain">);</span>
|
|
<span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">CREATED_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::copy_subtree</span><span class="plain">(</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>look_for</span><span class="plain">, </span><span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, 0);</span>
|
|
<span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>next</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">CREATED_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::copy_subtree</span><span class="plain">(</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>what_to_make</span><span class="plain">, </span><span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>next</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, 0);</span>
|
|
<span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>next</span><span class="plain">-</span><span class="element">>next</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="comment">restore the <code class="display"><span class="extract">EVERY_NT</span></code> node, now that the tree containing it has been copied:</span>
|
|
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>substitute_at</span><span class="plain">, </span><span class="constant">EVERY_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_subject</span><span class="plain">(</span><span class="identifier">g</span><span class="plain">-</span><span class="element">>substitute_at</span><span class="plain">, </span><span class="identifier">infs_k</span><span class="plain">);</span>
|
|
|
|
<span class="comment">insert this sentence after the current assembly position:</span>
|
|
<span class="identifier">new_sentence</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">assembly_position</span><span class="plain">-</span><span class="element">>next</span><span class="plain">;</span>
|
|
<span class="identifier">assembly_position</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">new_sentence</span><span class="plain">;</span>
|
|
<span class="identifier">assembly_position</span><span class="plain"> = </span><span class="identifier">new_sentence</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">ASSEMBLIES</span><span class="plain">,</span>
|
|
<span class="string">"Subject $j satisfies generalisation %d (from $j), making sentence:\</span><span class="plain">n</span><span class="string">$T"</span><span class="plain">,</span>
|
|
<span class="identifier">infs</span><span class="plain">, </span><span class="identifier">g</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">infs_k</span><span class="plain">, </span><span class="identifier">new_sentence</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Assertions::Assemblies::satisfies_generalisation is used in <a href="#SP12_1">§12.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_1"></a><b>§14.1. </b>The "implicitness count" is a generation count, where the sentences
|
|
from the original source text are generation 0, and any sentences created
|
|
from those are generation 1, and so on. This should never be more than a
|
|
dozen or so, and if it becomes large than we can be pretty sure that the
|
|
machinery is in infinite regress, e.g., because each K must contain an
|
|
L but each L must contain a K.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_ASSEMBLY_SIZE</span><span class="plain"> 500</span>
|
|
</pre>
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Throw the infinite regress exception if the current sentence makes too many things</span> <span class="cwebmacronumber">14.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">implicit_recursion_exception</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="constant">implicitness_count_ANNOT</span><span class="plain">) >= </span><span class="constant">MAX_ASSEMBLY_SIZE</span><span class="plain">) {</span>
|
|
<span class="identifier">implicit_recursion_exception</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_subject</span><span class="plain">(2, </span><span class="identifier">infs_k</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">max</span><span class="plain"> = </span><span class="constant">MAX_ASSEMBLY_SIZE</span><span class="plain">;</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(3, &</span><span class="identifier">max</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_AssemblyLoop</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"Making a new %2 seems to result in an assembly which can never end, "</span>
|
|
<span class="string">"or which at any rate led to some %3 further constructions "</span>
|
|
<span class="string">"before I panicked. This problem tends to occur if instructions "</span>
|
|
<span class="string">"are given which cause kinds to create each other forever: "</span>
|
|
<span class="string">"for instance, 'Every device is on a supporter. Every supporter "</span>
|
|
<span class="string">"is in a container. Every container is part of a device.'"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="9-rk.html">Back to 'Relation Knowledge'</a></li><li><a href="9-imp.html">Continue with 'Implications'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|