mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
600 lines
65 KiB
HTML
600 lines
65 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Assemblies</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="../index.html">
|
|
<img src="../docs-src/Figures/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../compiler.html">compiler tools</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="../supervisor-module/index.html">supervisor</a></li>
|
|
</ul><h2>Inform7 Modules</h2><ul>
|
|
<li><a href="index.html"><span class="selectedlink">core</span></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="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul><h2>Inter Modules</h2><ul>
|
|
<li><a href="../bytecode-module/index.html">bytecode</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul><h2>Shared Modules</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of 'Assemblies' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#9">Chapter 9: The A-Parser</a></li><li><b>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="9-ass.html#SP1">§1. Definitions</a></li><li><a href="9-ass.html#SP6">§6. Initialisation</a></li><li><a href="9-ass.html#SP9">§9. New generalisations</a></li><li><a href="9-ass.html#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/ns, 7/oaf, 7/rs, 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/ns, 7/oaf, 7/rs, 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<button class="popup" onclick="togglePopup('usagePopup563')">...<span class="popuptext" id="usagePopup563">Usage of <b>Assertions::Assemblies::initialise_assemblies_data</b>:<br>Inference Subjects - <a href="16-is.html#SP10">§10</a></span></button></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="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<button class="popup" onclick="togglePopup('usagePopup564')">...<span class="popuptext" id="usagePopup564">Usage of <b>Assertions::Assemblies::name_object_after</b>:<br>The Creator - <a href="9-tc.html#SP8_4_1">§8.4.1</a></span></button></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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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="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<button class="popup" onclick="togglePopup('usagePopup565')">...<span class="popuptext" id="usagePopup565">Usage of <b>Assertions::Assemblies::what_this_is_named_after</b>:<br>none</span></button></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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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="identifier">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<button class="popup" onclick="togglePopup('usagePopup566')">...<span class="popuptext" id="usagePopup566">Usage of <b>Assertions::Assemblies::get_named_after_text</b>:<br>none</span></button></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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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="identifier">named_after_text</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></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<button class="popup" onclick="togglePopup('usagePopup567')">...<span class="popuptext" id="usagePopup567">Usage of <b>Assertions::Assemblies::make_generalisation</b>:<br>Make Assertions - <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></span></button></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"><a href="9-ass.html#SP10">Assertions::Assemblies::subtree_mentions_kind</a></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"><a href="9-ass.html#SP10">Assertions::Assemblies::subtree_mentions_kind</a></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:\nLook for: $T\nMake: $T\n"</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"><a href="9-ass.html#SP11">Assertions::Assemblies::ensure_all_generalisations_made</a></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="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"><a href="16-is.html#SP19">InferenceSubjects::as_nonobject_kind</a></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="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></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="9-ass.html#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="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></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="9-ass.html#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"><a href="14-ds.html#SP7">Descriptions::is_adjectives_plus_kind</a></span><span class="plain">(</span><span class="identifier">val</span><span class="plain">))) {</span>
|
|
<span class="functiontext"><a href="9-rpt.html#SP10">Assertions::Refiner::refine_from_simple_description</a></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="9-ass.html#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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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="identifier">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="9-ass.html#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:\n"</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="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></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="9-ass.html#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<button class="popup" onclick="togglePopup('usagePopup568')">...<span class="popuptext" id="usagePopup568">Usage of <b>Assertions::Assemblies::subtree_mentions_kind</b>:<br><a href="9-ass.html#SP9">§9</a></span></button></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"><a href="9-ass.html#SP10">Assertions::Assemblies::subtree_mentions_kind</a></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"><a href="9-ass.html#SP10">Assertions::Assemblies::subtree_mentions_kind</a></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="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<button class="popup" onclick="togglePopup('usagePopup569')">...<span class="popuptext" id="usagePopup569">Usage of <b>Assertions::Assemblies::ensure_all_generalisations_made</b>:<br><a href="9-ass.html#SP9">§9</a></span></button></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"><a href="16-is.html#SP13">InferenceSubjects::is_within</a></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"><a href="16-is.html#SP21">InferenceSubjects::domain</a></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"><a href="9-ass.html#SP12">Assertions::Assemblies::satisfies_generalisations</a></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="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<button class="popup" onclick="togglePopup('usagePopup570')">...<span class="popuptext" id="usagePopup570">Usage of <b>Assertions::Assemblies::satisfies_generalisations</b>:<br><a href="9-ass.html#SP11">§11</a>, Instances - <a href="5-ins.html#SP6">§6</a>, <a href="5-ins.html#SP19">§19</a></span></button></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"><a href="16-is.html#SP21">InferenceSubjects::domain</a></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"><a href="16-is.html#SP14">InferenceSubjects::narrowest_broader_subject</a></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"><a href="16-is.html#SP14">InferenceSubjects::narrowest_broader_subject</a></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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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="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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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"><a href="9-ass.html#SP14">Assertions::Assemblies::satisfies_generalisation</a></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="9-ass.html#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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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"><a href="16-is.html#SP16">InferenceSubjects::get_assemblies_data</a></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="9-ass.html#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<button class="popup" onclick="togglePopup('usagePopup571')">...<span class="popuptext" id="usagePopup571">Usage of <b>Assertions::Assemblies::satisfies_generalisation</b>:<br><a href="9-ass.html#SP12_1">§12.1</a></span></button></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"><a href="26-pc.html#SP6">Plugins::Call::detect_bodysnatching</a></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\n"</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">) + </span><span class="constant">1</span><span class="plain">);</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"><a href="9-rpt.html#SP1">Assertions::Refiner::noun_from_infs</a></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">, </span><span class="constant">0</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"> = </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">, </span><span class="constant">0</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">-></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:\n$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="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"> </span><span class="constant">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"><a href="2-sq.html#SP2">Problems::quote_subject</a></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="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></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="9-ass.html#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-->
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|