mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 08:34:22 +03:00
2122 lines
235 KiB
HTML
2122 lines
235 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>3/tnt</title>
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</a></h1>
|
|
<ul>
|
|
<li><a href="../compiler.html"><b>compiler</b></a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul>
|
|
<h2>Compiler Webs</h2>
|
|
<ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul>
|
|
<h2>Inbuild Modules</h2>
|
|
<ul>
|
|
<li><a href="../inbuild-module/index.html">inbuild</a></li>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
</ul>
|
|
<h2>Inform7 Modules</h2>
|
|
<ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul>
|
|
<h2>Inter Modules</h2>
|
|
<ul>
|
|
<li><a href="../inter-module/index.html">inter</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul>
|
|
<h2>Foundation</h2>
|
|
<ul>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of '3/sm' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">if</a></li><li><a href="index.html#3">Chapter 3: Space and Time</a></li><li><b>Spatial Model</b></li></ul><p class="purpose">A plugin which constructs the fundamental spatial model used by IF, to represent containment, support, carrying, wearing, and incorporation.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP7">§7. Initialisation</a></li><li><a href="#SP10">§10. Special inferences</a></li><li><a href="#SP11">§11. Special kinds</a></li><li><a href="#SP17">§17. Special properties</a></li><li><a href="#SP19">§19. Default appearances</a></li><li><a href="#SP20">§20. Composite noun-quantifiers</a></li><li><a href="#SP22">§22. Nowhere</a></li><li><a href="#SP25">§25. Here</a></li><li><a href="#SP28">§28. Completing the model, stages I and II</a></li><li><a href="#SP34">§34. Completing the model, stages III and IV</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>The "spatial model" is the aspect of the IF model world which represents
|
|
containment, support, carrying, wearing, and incorporation; say, a button
|
|
which is part of a shirt which is in a tumble-drier which is in a room
|
|
called the Laundry, where there's also a man carrying a box of washing
|
|
powder and wearing a dressing gown. That's quite a lot of concepts, but
|
|
note that it doesn't include the geographical model (directions, the map,
|
|
regions, and so on), which are formally separated from the spatial model
|
|
and are therefore managed by other plugins.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">This is the largest and most complicated of the plugins. It has two basic
|
|
tasks: to infer the spatial structure from context and rather vague indications
|
|
of kinds and forms of containment; and then to compile an Inform 6
|
|
representation of the result, which is quite a messy business.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Every inference subject contains a pointer to its own unique copy of the
|
|
following structure, though it will only be relevant for instances of
|
|
"room" and "thing" — the raw materials of our model world. The
|
|
fundamental spatial data we will keep for each object is its "progenitor",
|
|
which may be <code class="display"><span class="extract">NULL</span></code>, representing the object which immediately contains,
|
|
carries, wears, supports or incorporates 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">spatial_data</span><span class="plain"> {</span>
|
|
<span class="comment">fundamental spatial information about an object's location</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">progenitor</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">progenitor_set_at</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">part_flag</span><span class="plain">; </span> <span class="comment">is this a component part of something else?</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">here_flag</span><span class="plain">; </span> <span class="comment">was this declared simply as being "here"?</span>
|
|
|
|
<span class="comment">temporary storage needed when compiling spatial data to I6 code</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">object_tree_parent</span><span class="plain">; </span> <span class="comment">in/on/worn by/carried by tree structure</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">object_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">object_tree_sibling</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">incorp_tree_parent</span><span class="plain">; </span> <span class="comment">part-of tree structure</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">incorp_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">incorp_tree_sibling</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">I6_definition_depth</span><span class="plain">; </span> <span class="comment">i.e., how many arrows <code class="display"><span class="extract">-></span></code> appear in its I6 header</span>
|
|
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">spatial_data</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure spatial_data is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>Here, first, are the special kinds of inference needed to store these vague
|
|
indications of spatial structure:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">IS_ROOM_INF</span><span class="plain"> 50 </span> <span class="comment">is O a room?</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">CONTAINS_THINGS_INF</span><span class="plain"> 51 </span> <span class="comment">does O contain things?</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PARENTAGE_INF</span><span class="plain"> 52 </span> <span class="comment">where is O located?</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PARENTAGE_HERE_INF</span><span class="plain"> 53 </span> <span class="comment">located vaguely as "here"?</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PARENTAGE_NOWHERE_INF</span><span class="plain"> 54 </span> <span class="comment">located vaguely as "nowhere"?</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PART_OF_INF</span><span class="plain"> 55 </span> <span class="comment">is O a part of another object?</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>The Spatial plugin also needs to know about a considerable number of special
|
|
kinds and properties:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_room</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_thing</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_container</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_supporter</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_person</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_players_holdall</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_initial_appearance</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_wearable</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_fixed_in_place</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_component_parent</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_component_child</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_component_sibling</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_worn</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_mark_as_room</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_mark_as_thing</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_container</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_supporter</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_matching_key</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>We will also need constants to talk about the inference subjects which
|
|
correspond to four of the special kinds — ordinarily that would be redundant,
|
|
since you can get the subject as a function of the kind, but there's a tricky
|
|
timing issue to get around (see below).
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs_room</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs_thing</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs_supporter</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs_person</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Initialisation. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NEW_BASE_KIND_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_new_base_kind_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_ACT_ON_SPECIAL_NPS</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_act_on_special_NPs</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_COMPLETE_MODEL</span><span class="plain">, </span><span class="functiontext">PL::Spatial::IF_complete_model</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_DEFAULT_APPEARANCE</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_default_appearance</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_INFERENCES_CONTRADICT</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_inferences_contradict</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_EXPLAIN_CONTRADICTION</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_explain_contradiction</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_LOG_INFERENCE_TYPE</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_log_inference_type</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NAME_TO_EARLY_INFS</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_name_to_early_infs</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NEW_SUBJECT_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_new_subject_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NEW_PROPERTY_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_new_property_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_PARSE_COMPOSITE_NQS</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_parse_composite_NQs</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_SET_KIND_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_set_kind_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_SET_SUBKIND_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_set_subkind_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_ADD_TO_WORLD_INDEX</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_add_to_World_index</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_INTERVENE_IN_ASSERTION</span><span class="plain">, </span><span class="functiontext">PL::Spatial::spatial_intervene_in_assertion</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Create early inference subjects</span> <span class="cwebmacronumber">7.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::start appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_1"></a><b>§7.1. </b>In talking about some of the fundamental spatial domains we potentially have
|
|
a vicious circle, because
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) we need fundamental kinds like "thing" and "room" in order to
|
|
specify the domains for built-in relations like "containment",
|
|
</li><li>(b) we need built-in relations like "containment" in order to specify
|
|
the meanings of prepositional usages like "to be inside",
|
|
</li><li>(c) we need to have defined usages like "to be inside" in order to
|
|
break up sentences in the parse tree and identify their primary verbs and
|
|
noun phrases, but
|
|
</li><li>(d) we need a parse tree already in place before we can act on sentences
|
|
like "A room is a kind of object." which create the fundamental kinds.
|
|
</li></ul>
|
|
<p class="inwebparagraph">We break the deadlock at (a) by specifying the domains of the built-in
|
|
relations using inference subject structures created in advance of the
|
|
kinds they will one day infer about. These amount to promisory notes that
|
|
we will make them correspond to the actual kinds later on, at some point
|
|
after stage (d) when they exist.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Create early inference subjects</span> <span class="cwebmacronumber">7.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">infs_room</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::new</span><span class="plain">(</span><span class="identifier">global_constants</span><span class="plain">,</span>
|
|
<span class="identifier">FUND_SUB</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
<span class="identifier">infs_thing</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::new</span><span class="plain">(</span><span class="identifier">global_constants</span><span class="plain">,</span>
|
|
<span class="identifier">FUND_SUB</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
<span class="identifier">infs_supporter</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::new</span><span class="plain">(</span><span class="identifier">global_constants</span><span class="plain">,</span>
|
|
<span class="identifier">FUND_SUB</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
<span class="identifier">infs_person</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::new</span><span class="plain">(</span><span class="identifier">global_constants</span><span class="plain">,</span>
|
|
<span class="identifier">FUND_SUB</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">, </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>And this is where those IOUs are redeemed. What happens is that, ordinarily,
|
|
the machinery creating objects (and kinds) will allocate a new inference
|
|
structure for each object, but it first invites plugins to choose an existing
|
|
one instead. (The INFS structure is rewritten, but the important thing is that
|
|
pointers to it remain consistent and valid.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_name_to_early_infs</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">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="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_room</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">infs_room</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_thing</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">infs_thing</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="comment">container isn't an early case, surprisingly</span>
|
|
<span class="reserved">case</span><span class="plain"> 3: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_supporter</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">infs_supporter</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 4: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_person</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">infs_person</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</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 PL::Spatial::spatial_name_to_early_infs is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>Here we initialise the data used by Spatial for each object:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">spatial_data</span><span class="plain"> *</span><span class="functiontext">PL::Spatial::new_data</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain">) {</span>
|
|
<span class="reserved">spatial_data</span><span class="plain"> *</span><span class="identifier">sd</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">spatial_data</span><span class="plain">);</span>
|
|
<span class="identifier">sd</span><span class="plain">-</span><span class="element">>progenitor</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">sd</span><span class="plain">-</span><span class="element">>progenitor_set_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">sd</span><span class="plain">-</span><span class="element">>part_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">sd</span><span class="plain">-</span><span class="element">>object_tree_parent</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">sd</span><span class="plain">-</span><span class="element">>object_tree_child</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">sd</span><span class="plain">-</span><span class="element">>object_tree_sibling</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">sd</span><span class="plain">-</span><span class="element">>incorp_tree_child</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">sd</span><span class="plain">-</span><span class="element">>incorp_tree_sibling</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">sd</span><span class="plain">-</span><span class="element">>incorp_tree_parent</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">sd</span><span class="plain">-</span><span class="element">>I6_definition_depth</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">sd</span><span class="plain">-</span><span class="element">>here_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sd</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::new_data is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Special inferences. </b>Four of these are quite simple inferences, but <code class="display"><span class="extract">PARENTAGE_INF</span></code> stores the
|
|
object to which a spatial relationship is being inferred; and this means that
|
|
multiple <code class="display"><span class="extract">PARENTAGE_INF</span></code>s can contradict each other.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_log_inference_type</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">it</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">it</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CONTAINS_THINGS_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"CONTAINS_THINGS_INF"</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">case</span><span class="plain"> </span><span class="constant">IS_ROOM_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"IS_ROOM_INF"</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">case</span><span class="plain"> </span><span class="constant">PARENTAGE_HERE_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"PARENTAGE_HERE_INF"</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">case</span><span class="plain"> </span><span class="constant">PARENTAGE_NOWHERE_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"PARENTAGE_NOWHERE_INF"</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">case</span><span class="plain"> </span><span class="constant">PARENTAGE_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"PARENTAGE_INF"</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">case</span><span class="plain"> </span><span class="constant">PART_OF_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"PART_OF_INF"</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="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_inferences_contradict</span><span class="plain">(</span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">similarity</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">World::Inferences::get_inference_type</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">) == </span><span class="constant">PARENTAGE_INF</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">) !=</span>
|
|
<span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">B</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>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_explain_contradiction</span><span class="plain">(</span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">similarity</span><span class="plain">,</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">World::Inferences::get_inference_type</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">) == </span><span class="constant">PARENTAGE_INF</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">) !=</span>
|
|
<span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">B</span><span class="plain">))) {</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(2, </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">B</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_subject</span><span class="plain">(3, </span><span class="identifier">subj</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(4, </span><span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(5, </span><span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">B</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SpatialContradiction</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"You wrote %1, but also %2: that seems to be saying that the same "</span>
|
|
<span class="string">"object (%3) must be in two different places (%4 and %5). This "</span>
|
|
<span class="string">"looks like a contradiction. %P"</span>
|
|
<span class="string">"This sometimes happens as a result of a sentence like 'Every person "</span>
|
|
<span class="string">"carries a bag', when Inform doesn't know 'bag' as the name of any "</span>
|
|
<span class="string">"kind - so that it makes only a single thing called 'bag', and then "</span>
|
|
<span class="string">"the sentence looks as if it says everyone is carrying the same bag."</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="identifier">TRUE</span><span class="plain">;</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 PL::Spatial::spatial_log_inference_type is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="endnote">The function PL::Spatial::spatial_inferences_contradict is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="endnote">The function PL::Spatial::spatial_explain_contradiction is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. Special kinds. </b>These are kind names to do with spatial layout which Inform provides special
|
|
support for; it recognises the Englishs name when defined by the Standard
|
|
Rules. (So there is no need to translate this to other languages.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">> ::=</span>
|
|
<span class="identifier">room</span><span class="plain"> |</span>
|
|
<span class="identifier">thing</span><span class="plain"> |</span>
|
|
<span class="identifier">container</span><span class="plain"> |</span>
|
|
<span class="identifier">supporter</span><span class="plain"> |</span>
|
|
<span class="identifier">person</span><span class="plain"> |</span>
|
|
<span class="identifier">player</span><span class="character">'s holdall</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_new_base_kind_notify</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">new_base</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</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">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">K_room</span><span class="plain"> = </span><span class="identifier">new_base</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">case</span><span class="plain"> 1: </span><span class="identifier">K_thing</span><span class="plain"> = </span><span class="identifier">new_base</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">case</span><span class="plain"> 2: </span><span class="identifier">K_container</span><span class="plain"> = </span><span class="identifier">new_base</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">case</span><span class="plain"> 3: </span><span class="identifier">K_supporter</span><span class="plain"> = </span><span class="identifier">new_base</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">case</span><span class="plain"> 4: </span><span class="identifier">K_person</span><span class="plain"> = </span><span class="identifier">new_base</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">case</span><span class="plain"> 5: </span><span class="identifier">K_players_holdall</span><span class="plain"> = </span><span class="identifier">new_base</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="plain">}</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>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_new_subject_notify</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain">) {</span>
|
|
<span class="identifier">CREATE_PF_DATA</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">subj</span><span class="plain">, </span><span class="functiontext">PL::Spatial::new_data</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 PL::Spatial::spatial_new_base_kind_notify is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="endnote">The function PL::Spatial::spatial_new_subject_notify is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>When the rest of Inform makes something a room, for instance in response to
|
|
an explicit sentence like "The Hall of Mirrors is a room.", we take notice;
|
|
if it turns out to be news, we infer <code class="display"><span class="extract">IS_ROOM_INF</span></code> with certainty.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_set_kind_notify</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kw</span><span class="plain"> = </span><span class="identifier">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((!(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">kw</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">))) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">)))</span>
|
|
<span class="identifier">World::Inferences::draw</span><span class="plain">(</span><span class="constant">IS_ROOM_INF</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">,</span>
|
|
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</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 PL::Spatial::spatial_set_kind_notify is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>Nothing in the core Inform language prevents room from being made a kind
|
|
of vehicle, and so on, but this would cause mayhem in the model world. So:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_set_subkind_notify</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">sub</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">super</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_thing</span><span class="plain">) && (</span><span class="identifier">super</span><span class="plain"> != </span><span class="identifier">K_object</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ThingAdrift</span><span class="plain">),</span>
|
|
<span class="string">"'thing' is not allowed to be a kind of anything (other than "</span>
|
|
<span class="string">"'object')"</span><span class="plain">,</span>
|
|
<span class="string">"because it's too fundamental to the way Inform uses rooms "</span>
|
|
<span class="string">"and things to model the physical world."</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="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_room</span><span class="plain">) && (</span><span class="identifier">super</span><span class="plain"> != </span><span class="identifier">K_object</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RoomAdrift</span><span class="plain">),</span>
|
|
<span class="string">"'room' is not allowed to be a kind of anything (other than "</span>
|
|
<span class="string">"'object')"</span><span class="plain">,</span>
|
|
<span class="string">"because it's too fundamental to the way Inform uses rooms "</span>
|
|
<span class="string">"and things to model the physical world."</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="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_container</span><span class="plain">) && (</span><span class="identifier">super</span><span class="plain"> == </span><span class="identifier">K_supporter</span><span class="plain">)) ||</span>
|
|
<span class="plain">((</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_supporter</span><span class="plain">) && (</span><span class="identifier">super</span><span class="plain"> == </span><span class="identifier">K_container</span><span class="plain">))) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ContainerAdrift</span><span class="plain">),</span>
|
|
<span class="string">"'container' and 'supporter' are not allowed to be kinds "</span>
|
|
<span class="string">"of each other"</span><span class="plain">,</span>
|
|
<span class="string">"because they're too fundamental to the way Inform models the "</span>
|
|
<span class="string">"physical world. Both are kinds of 'thing', but they are "</span>
|
|
<span class="string">"different, and no object is allowed to belong to both at once."</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="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 PL::Spatial::spatial_set_subkind_notify is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. </b>This tests whether an object is an instance of "room":
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">spatial_plugin</span><span class="plain">)) && (</span><span class="identifier">K_room</span><span class="plain">) && (</span><span class="identifier">I</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_room</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 PL::Spatial::object_is_a_room is used in <a href="#SP32_3_2">§32.3.2</a>, <a href="#SP32_3_3">§32.3.3</a>, <a href="#SP33">§33</a>, <a href="#SP41">§41</a>, <a href="#SP44">§44</a>, 3/tnt (<a href="3-tnt.html#SP11_1">§11.1</a>), 3/tp (<a href="3-tp.html#SP12_1">§12.1</a>, <a href="3-tp.html#SP12_3">§12.3</a>), 3/rgn (<a href="3-rgn.html#SP18">§18</a>), 3/tm (<a href="3-tm.html#SP23_2">§23.2</a>, <a href="3-tm.html#SP37_1">§37.1</a>, <a href="3-tm.html#SP37_2">§37.2</a>, <a href="3-tm.html#SP37_4">§37.4</a>), 3/sm2 (<a href="3-sm2.html#SP6">§6</a>, <a href="3-sm2.html#SP8_16">§8.16</a>), 3/em (<a href="3-em.html#SP11">§11</a>, <a href="3-em.html#SP22_2">§22.2</a>, <a href="3-em.html#SP22_4_1">§22.4.1</a>, <a href="3-em.html#SP25_6">§25.6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>This is where we give Inform the numbers it needs to write the "a world
|
|
with 5 rooms and 27 things"-style text in a successful report on its run.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::get_world_size</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">rooms</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">things</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="plain">*</span><span class="identifier">rooms</span><span class="plain"> = 0; *</span><span class="identifier">things</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">LOOP_OVER_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">) (*</span><span class="identifier">rooms</span><span class="plain">)++;</span>
|
|
<span class="identifier">LOOP_OVER_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_thing</span><span class="plain">) (*</span><span class="identifier">things</span><span class="plain">)++;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::get_world_size appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. Special properties. </b>These are property names to do with spatial layout which Inform provides
|
|
special support for; it recognises the English names when they are defined by
|
|
the Standard Rules. (So there is no need to translate this to other languages.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">"Matching key" has to appear in here because it both has a traditional I6
|
|
name and is used as relation storage. If we didn't care about it being
|
|
called <code class="display"><span class="extract">with_key</span></code> in the I6 source code, we wouldn't need to do anything
|
|
special with it at all.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">properties</span><span class="plain">> ::=</span>
|
|
<span class="identifier">initial</span><span class="plain"> </span><span class="identifier">appearance</span><span class="plain"> |</span>
|
|
<span class="identifier">wearable</span><span class="plain"> |</span>
|
|
<span class="identifier">fixed</span><span class="plain"> </span><span class="identifier">in</span><span class="plain"> </span><span class="identifier">place</span><span class="plain"> |</span>
|
|
<span class="identifier">matching</span><span class="plain"> </span><span class="identifier">key</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_new_property_notify</span><span class="plain">(</span><span class="identifier">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">properties</span><span class="plain">>(</span><span class="identifier">prn</span><span class="plain">-</span><span class="element">>name</span><span class="plain">)) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">P_initial_appearance</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">P_wearable</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 2: </span><span class="identifier">P_fixed_in_place</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 3: </span><span class="identifier">P_matching_key</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">;</span>
|
|
<span class="identifier">Properties::set_translation</span><span class="plain">(</span><span class="identifier">P_matching_key</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"with_key"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</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 PL::Spatial::spatial_new_property_notify is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. Default appearances. </b>Spatial gets to decide here what raw text following a new object will be
|
|
taken to mean: for scenery it will be the "description" (i.e., the text
|
|
produced on examining), for any other thing it will be the "initial
|
|
appearance".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_default_appearance</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">txt</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">InferenceSubjects::is_within</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_object</span><span class="plain">))) {</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">set_prn</span><span class="plain"> = </span><span class="identifier">P_description</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">InferenceSubjects::is_within</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_thing</span><span class="plain">))) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</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="identifier">I</span><span class="plain">) && (</span><span class="functiontext">PL::Backdrops::object_is_scenery</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">))) {</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">PROPERTY_INF</span><span class="plain">) {</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="identifier">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">prn</span><span class="plain">) && (</span><span class="identifier">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) > 0)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">P_description</span><span class="plain">)) {</span>
|
|
<<span class="cwebmacro">Produce a problem for doubly described scenery</span> <span class="cwebmacronumber">19.1</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="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">set_prn</span><span class="plain"> = </span><span class="identifier">P_initial_appearance</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">set_prn</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</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="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 PL::Spatial::spatial_default_appearance is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19_1"></a><b>§19.1. </b>A lone string as a sentence is a description for a room, but an initial
|
|
description for an object. Only now can we know which, since we have only
|
|
just decided whether <code class="display"><span class="extract">I</span></code> is a room or not. We therefore draw the necessary
|
|
inference.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Produce a problem for doubly described scenery</span> <span class="cwebmacronumber">19.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::Issue::object_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SceneryDoublyDescribed</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"is scenery, which means that it cannot sensibly have any 'initial "</span>
|
|
<span class="string">"appearance' property - being scenery, it isn't announced when the "</span>
|
|
<span class="string">"player first sees it. That means the quoted text about it has to "</span>
|
|
<span class="string">"be read as its 'description' instead, seen when the player examines "</span>
|
|
<span class="string">"it. But the source text writes out its description, too"</span><span class="plain">,</span>
|
|
<span class="string">"which means we have a subtle little contradiction here."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP19">§19</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. Composite noun-quantifiers. </b>"Nothing" is conspicuously absent from the possibilities below. It gets
|
|
special treatment elsewhere since it can also double as a value (the "not
|
|
an object" pseudo-value).
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">nouns</span><span class="plain">> ::=</span>
|
|
<span class="identifier">_something</span><span class="plain">/</span><span class="identifier">anything</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_thing</span>
|
|
<span class="identifier">_somewhere</span><span class="plain">/</span><span class="identifier">anywhere</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_room</span>
|
|
<span class="identifier">_someone</span><span class="plain">/</span><span class="identifier">anyone</span><span class="plain">/</span><span class="identifier">somebody</span><span class="plain">/</span><span class="identifier">anybody</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_person</span>
|
|
<span class="identifier">_everything</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_thing</span><span class="plain">; <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">for_all_quantifier</span>
|
|
<span class="identifier">_everywhere</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_room</span><span class="plain">; <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">for_all_quantifier</span>
|
|
<span class="identifier">_everyone</span><span class="plain">/</span><span class="identifier">everybody</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_person</span><span class="plain">; <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">for_all_quantifier</span>
|
|
<span class="identifier">_nowhere</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_room</span><span class="plain">; <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">not_exists_quantifier</span>
|
|
<span class="identifier">_nobody</span><span class="plain">/</span><span class="identifier">no</span><span class="plain">-</span><span class="identifier">one</span><span class="plain"> *** | ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_person</span><span class="plain">; <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">not_exists_quantifier</span>
|
|
<span class="identifier">_no</span><span class="plain"> </span><span class="identifier">_one</span><span class="plain"> *** ==> 0; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">K_person</span><span class="plain">; <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">not_exists_quantifier</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b>Words like "something" or "everywhere" combine a common noun — thing,
|
|
and implicitly room — with a determiner — one thing, all rooms. When we
|
|
detect them, we set both <code class="display"><span class="extract">quantifier_used</span></code> and <code class="display"><span class="extract">some_kind</span></code> appropriately.
|
|
None can be recognised if the basic kinds are not created yet, which we
|
|
check for by inspecting <code class="display"><span class="extract">K_thing</span></code>. (Note that the S-parser may indeed be
|
|
asked to parse "something" before this point, as when it scans the
|
|
domains of adjective definitions, but that it's okay that it produces a
|
|
null result.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">With the "some-" words, no quantifier is set because the meaning here is
|
|
the <code class="display"><span class="extract">exists_quantifier</span></code>. Since this is the default behaviour for
|
|
unquantified descriptions anyway — "a door is in the Great Hall" means
|
|
that such a door exists — we needn't set the variable.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_parse_composite_NQs</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">DW</span><span class="plain">,</span>
|
|
<span class="identifier">quantifier</span><span class="plain"> **</span><span class="identifier">quant</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">some_kind</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_thing</span><span class="plain">) {</span>
|
|
<span class="plain"><<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>> = </span><span class="identifier">NULL</span><span class="plain">; <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">nouns</span><span class="plain">>(*</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="plain">*</span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Wordings::from</span><span class="plain">(*</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">nouns</span><span class="plain">>, 1)));</span>
|
|
<span class="plain">*</span><span class="identifier">quant</span><span class="plain"> = <<</span><span class="identifier">quantifier</span><span class="plain">:</span><span class="identifier">q</span><span class="plain">>>; *</span><span class="identifier">some_kind</span><span class="plain"> = <<</span><span class="identifier">kind</span><span class="plain">:</span><span class="identifier">k</span><span class="plain">>>;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</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 PL::Spatial::spatial_parse_composite_NQs is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. Nowhere. </b>This means the same as "nothing", in a noun context, but we annotate a parse
|
|
node using this wording in order to produce better problem messages if need be.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">-</span><span class="identifier">phrases</span><span class="plain">> ::=</span>
|
|
<span class="identifier">nowhere</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_act_on_special_NPs</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">spatial</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">-</span><span class="identifier">phrases</span><span class="plain">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Word::unexpectedly_upper_case</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) == </span><span class="identifier">FALSE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">K_room</span><span class="plain">)) {</span>
|
|
<span class="identifier">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">Rvalues::new_nothing_object_constant</span><span class="plain">());</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">nowhere_ANNOT</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">TRUE</span><span class="plain">;</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 PL::Spatial::spatial_act_on_special_NPs is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. </b>Now in fact this often does get picked up:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_intervene_in_assertion</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">, </span><span class="identifier">nowhere_ANNOT</span><span class="plain">)) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">left_subject</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_subject</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">left_subject</span><span class="plain">))</span>
|
|
<span class="identifier">Problems::Issue::subject_problem_at_sentence</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_KindNowhere</span><span class="plain">),</span>
|
|
<span class="identifier">left_subject</span><span class="plain">,</span>
|
|
<span class="string">"seems to be said to be 'nowhere' in some way"</span><span class="plain">,</span>
|
|
<span class="string">"which doesn't make sense. An individual thing can be 'nowhere', "</span>
|
|
<span class="string">"but here we're talking about a whole kind, and it's not allowed "</span>
|
|
<span class="string">"to talk about general locations of a whole kind of things at once."</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span>
|
|
<span class="identifier">Calculus::Propositions::Abstract::to_put_nowhere</span><span class="plain">(), </span><span class="identifier">left_subject</span><span class="plain">, </span><span class="identifier">prevailing_mood</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="plain">}</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 PL::Spatial::spatial_intervene_in_assertion is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. Here. </b>A sentence like "The sonic screwdriver is here." is not copular, but instead
|
|
expresses a relationship — "here" is not a value but a relation to an
|
|
unstated object. That object is the room we're currently talking about, which
|
|
sounds easy to work out, but isn't: we don't yet know which of the objects
|
|
being talked about will eventually turn out to be rooms. As a result, "here"
|
|
needs delicate handling, and its own inference type.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The fact that rooms cannot be "here" is useful, because it means Inform can
|
|
with certainty read
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The washing machine is here. The shirt is in the machine.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">as creating a container called "washing machine", not a room.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::infer_presence_here</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="constant">PARENTAGE_HERE_INF</span><span class="plain">) {</span>
|
|
<span class="identifier">Problems::Issue::contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DuplicateHere</span><span class="plain">),</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">),</span>
|
|
<span class="identifier">current_sentence</span><span class="plain">,</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"can only be said to be 'here' once"</span><span class="plain">,</span>
|
|
<span class="string">"in a single assertion sentence. This avoids potential confusion, "</span>
|
|
<span class="string">"since 'here' can mean different things in different sentences."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">World::Inferences::draw</span><span class="plain">(</span><span class="constant">PARENTAGE_HERE_INF</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">,</span>
|
|
<span class="identifier">Assertions::Traverse::get_current_subject</span><span class="plain">(), </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">World::Inferences::draw</span><span class="plain">(</span><span class="constant">IS_ROOM_INF</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">IMPOSSIBLE_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::infer_presence_here appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. </b>Similarly:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::infer_presence_nowhere</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">World::Inferences::draw</span><span class="plain">(</span><span class="constant">PARENTAGE_NOWHERE_INF</span><span class="plain">,</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">World::Inferences::draw</span><span class="plain">(</span><span class="constant">IS_ROOM_INF</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">IMPOSSIBLE_CE</span><span class="plain">,</span>
|
|
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::infer_presence_nowhere appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. Completing the model, stages I and II. </b>That's enough preliminaries; time to get on with adding a sense of space
|
|
to the model world.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::IF_complete_model</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">stage</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="functiontext">PL::Spatial::spatial_stage_I</span><span class="plain">(); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 2: </span><span class="functiontext">PL::Spatial::spatial_stage_II</span><span class="plain">(); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 3: </span><span class="functiontext">PL::Spatial::spatial_stage_III</span><span class="plain">(); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 4: </span><span class="functiontext">PL::Spatial::spatial_stage_IV</span><span class="plain">(); </span><span class="reserved">break</span><span class="plain">;</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 PL::Spatial::IF_complete_model is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. </b>Recall that as we begin stage I of model creation, all objects are, of
|
|
course, created, and they have kinds associated with them if the source
|
|
text has said explicitly what kind they have: but that is not good enough.
|
|
It often happens that the source implicitly specifies a kind, and we need
|
|
to take note. If X is in Y, then Y might be a room, or a region, or a
|
|
container, and we might need to look at other sentences — say, establishing
|
|
that Y is the destination of a map connection — to see which.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_stage_I</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Perform kind determination for this object</span> <span class="cwebmacronumber">29.1</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 PL::Spatial::spatial_stage_I is used in <a href="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1"></a><b>§29.1. </b>Our main problem in what follows is caused by "in" being so ambiguous,
|
|
or perhaps it might be said that the real problem is that we choose to
|
|
distinguish between rooms and containers on a world-modelling level — when it
|
|
could well be argued that they are linguistically the same thing.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It means that Inform is often reading code such as:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The croquet ball is in the Boxed Set.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">and not being sure whether "Boxed Set" is a container or a room.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In the following determination, we use two sources of information. One is explicit
|
|
data given by the source text or unambiguously implied in it, like so —
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The Boxed Set is a container. The spoon is on the low table.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">which tell us the Boxed Set is certainly a container and the table certainly
|
|
a supporter. This information about an object is the "designer choice" about
|
|
its kind.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The other source of information comes from less definite sentences using words
|
|
like "in", and from the spatial context in which the object appears. This
|
|
is the "geography choice" for its kind.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Perform kind determination for this object</span> <span class="cwebmacronumber">29.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">Instances::get_creating_sentence</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">designers_choice</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Determine the designer choice</span> <span class="cwebmacronumber">29.1.1</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">geography_choice</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">geography_inference</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">geography_certainty</span><span class="plain"> = </span><span class="identifier">UNKNOWN_CE</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Determine the geography choice</span> <span class="cwebmacronumber">29.1.2</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">geography_choice</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">geography_choice</span><span class="plain">, </span><span class="identifier">designers_choice</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Attempt to reconcile the two choices</span> <span class="cwebmacronumber">29.1.3</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">K_object</span><span class="plain">))</span>
|
|
<span class="identifier">Calculus::Propositions::Abstract::assert_kind_of_object</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_thing</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29">§29</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_1"></a><b>§29.1.1. </b>By this point, any explicit information is reflected in the hierarchy of
|
|
kinds. We look out for four specialised kinds of thing, but failing that,
|
|
we simply take its broadest kind — usually "thing", "room", "direction"
|
|
or "region".
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Determine the designer choice</span> <span class="cwebmacronumber">29.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">f</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="identifier">infs</span><span class="plain">; </span><span class="identifier">infs</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_kind</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="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
|
|
<span class="identifier">f</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">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">f</span><span class="plain">, </span><span class="identifier">K_container</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">f</span><span class="plain">, </span><span class="identifier">K_supporter</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">f</span><span class="plain">, </span><span class="identifier">K_door</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">f</span><span class="plain">, </span><span class="identifier">K_person</span><span class="plain">)))</span>
|
|
<span class="identifier">designers_choice</span><span class="plain"> = </span><span class="identifier">f</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">designers_choice</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">designers_choice</span><span class="plain"> = </span><span class="identifier">f</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1">§29.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_2"></a><b>§29.1.2. </b>If there is any positive information that this is a room, that's the
|
|
geography choice; otherwise it's whichever of room or container is more
|
|
probably suggested by inferences.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Determine the geography choice</span> <span class="cwebmacronumber">29.1.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">CONTAINS_THINGS_INF</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) > </span><span class="identifier">geography_certainty</span><span class="plain">) {</span>
|
|
<span class="identifier">geography_choice</span><span class="plain"> = </span><span class="identifier">K_container</span><span class="plain">;</span>
|
|
<span class="identifier">geography_certainty</span><span class="plain"> = </span><span class="identifier">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="identifier">geography_inference</span><span class="plain"> = </span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">IS_ROOM_INF</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) > </span><span class="identifier">UNKNOWN_CE</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) > </span><span class="identifier">geography_certainty</span><span class="plain">)) {</span>
|
|
<span class="identifier">geography_choice</span><span class="plain"> = </span><span class="identifier">K_room</span><span class="plain">;</span>
|
|
<span class="identifier">geography_certainty</span><span class="plain"> = </span><span class="identifier">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="identifier">geography_inference</span><span class="plain"> = </span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1">§29.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_3"></a><b>§29.1.3. </b>Since the designer choice is the one currently in force, we have basically
|
|
three choices here: impose the geography choice instead; do nothing; or issue
|
|
a problem message. The case where we do nothing is if geography suggests
|
|
something is a room, when it's actually a door: this is because sentences
|
|
like "East is the Marble Portal" can suggest the "Marble Portal" is a room
|
|
when it's legitimately a door.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Attempt to reconcile the two choices</span> <span class="cwebmacronumber">29.1.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">sentence_setting_kind</span><span class="plain"> = </span><span class="identifier">Instances::get_kind_set_sentence</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">designers_choice</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
|
|
<span class="plain">((</span><span class="identifier">geography_certainty</span><span class="plain"> == </span><span class="identifier">CERTAIN_CE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">geography_choice</span><span class="plain">, </span><span class="identifier">designers_choice</span><span class="plain">))))</span>
|
|
<<span class="cwebmacro">Accept the geography choice, since it only refines what we already know</span> <span class="cwebmacronumber">29.1.3.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">geography_certainty</span><span class="plain"> == </span><span class="identifier">CERTAIN_CE</span><span class="plain">) &&</span>
|
|
<span class="plain">(!((</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">designers_choice</span><span class="plain">, </span><span class="identifier">K_door</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">geography_choice</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">)))))</span>
|
|
<<span class="cwebmacro">Issue a problem message, since the choices are irreconcilable</span> <span class="cwebmacronumber">29.1.3.2</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1">§29.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_3_1"></a><b>§29.1.3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Accept the geography choice, since it only refines what we already know</span> <span class="cwebmacronumber">29.1.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CHANGES</span><span class="plain">, </span><span class="string">"Accepting geography choice of kind of $O as $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">I</span><span class="plain">, </span><span class="identifier">geography_choice</span><span class="plain">);</span>
|
|
<span class="identifier">Calculus::Propositions::Abstract::assert_kind_of_object</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">geography_choice</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1_3">§29.1.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_3_2"></a><b>§29.1.3.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message, since the choices are irreconcilable</span> <span class="cwebmacronumber">29.1.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Choices: designer $u, geography $u.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">designers_choice</span><span class="plain">, </span><span class="identifier">geography_choice</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">decider</span><span class="plain"> = </span><span class="identifier">Instances::get_creating_sentence</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sentence_setting_kind</span><span class="plain">) </span><span class="identifier">decider</span><span class="plain"> = </span><span class="identifier">sentence_setting_kind</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">designers_choice</span><span class="plain">, </span><span class="identifier">K_person</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Issue a problem message for implied containment by a person</span> <span class="cwebmacronumber">29.1.3.2.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">designers_choice</span><span class="plain">, </span><span class="identifier">K_supporter</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">geography_choice</span><span class="plain">, </span><span class="identifier">K_container</span><span class="plain">)))</span>
|
|
<<span class="cwebmacro">Issue a problem message for simultaneous containment and support</span> <span class="cwebmacronumber">29.1.3.2.2</span>>
|
|
<span class="reserved">else</span>
|
|
<<span class="cwebmacro">Issue a more generic problem message for irreconcilable kinds</span> <span class="cwebmacronumber">29.1.3.2.3</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1_3">§29.1.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_3_2_1"></a><b>§29.1.3.2.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message for implied containment by a person</span> <span class="cwebmacronumber">29.1.3.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::Issue::contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PersonContaining</span><span class="plain">),</span>
|
|
<span class="identifier">sentence_setting_kind</span><span class="plain">,</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">geography_inference</span><span class="plain">), </span><span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"cannot contain or support things like something inanimate"</span><span class="plain">,</span>
|
|
<span class="string">"which is what you are implying. Instead, people must carry or wear them: "</span>
|
|
<span class="string">"so 'The briefcase is in Daphne.' is disallowed, but 'The briefcase is "</span>
|
|
<span class="string">"carried by Daphne.' is fine, or indeed 'Daphne carries the briefcase.'"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1_3_2">§29.1.3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_3_2_2"></a><b>§29.1.3.2.2. </b>A notorious problem message for a notorious limitation of the traditional
|
|
Inform spatial model:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message for simultaneous containment and support</span> <span class="cwebmacronumber">29.1.3.2.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::Issue::contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantContainAndSupport</span><span class="plain">),</span>
|
|
<span class="identifier">decider</span><span class="plain">, </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">geography_inference</span><span class="plain">), </span><span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"cannot both contain things and support things"</span><span class="plain">,</span>
|
|
<span class="string">"which is what you're implying here. If you need both, the easiest way is "</span>
|
|
<span class="string">"to make it either a supporter with a container attached or vice versa. "</span>
|
|
<span class="string">"For instance: 'A desk is here. On the desk is a newspaper. An openable "</span>
|
|
<span class="string">"container called the drawer is part of the desk. In the drawer is a "</span>
|
|
<span class="string">"stapler.'"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1_3_2">§29.1.3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29_1_3_2_3"></a><b>§29.1.3.2.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a more generic problem message for irreconcilable kinds</span> <span class="cwebmacronumber">29.1.3.2.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::Issue::contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BothRoomAndSupporter</span><span class="plain">),</span>
|
|
<span class="identifier">decider</span><span class="plain">,</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">geography_inference</span><span class="plain">), </span><span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"would need to have two different and incompatible kinds to make both "</span>
|
|
<span class="string">"sentences true"</span><span class="plain">,</span>
|
|
<span class="string">"and this is a contradiction."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP29_1_3_2">§29.1.3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. </b>Stage II at last. Now the kinds are all known, and it's time to work out
|
|
the spatial arrangements. Inform's spatial model assigns every instance object
|
|
a unique "progenitor", which may be <code class="display"><span class="extract">NULL</span></code>, representing the object which
|
|
immediately contains, carries, wears, supports or incorporates it.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Clearly if we know every object's progenitor, then we know the whole spatial
|
|
layout — it's all just elaboration from there. (See Stage III below.) But
|
|
since other plugins can decide on this, not just Spatial, we had better
|
|
provide access routines to read and write:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</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">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">spatial_plugin</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>progenitor</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::set_progenitor</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">of</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">reason</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">spatial_plugin</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"spatial plugin inactive"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</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">"set progenitor of nothing"</span><span class="plain">);</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">of</span><span class="plain">)-</span><span class="element">>progenitor</span><span class="plain"> = </span><span class="identifier">to</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">of</span><span class="plain">)-</span><span class="element">>progenitor_set_at</span><span class="plain"> =</span>
|
|
<span class="plain">(</span><span class="identifier">reason</span><span class="plain">)?</span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">reason</span><span class="plain">):</span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::progenitor is used in <a href="#SP32_2">§32.2</a>, <a href="#SP37">§37</a>, <a href="#SP38_2">§38.2</a>, <a href="#SP38_2_1">§38.2.1</a>, <a href="#SP38_3">§38.3</a>, <a href="#SP38_4">§38.4</a>, <a href="#SP42">§42</a>, <a href="#SP44">§44</a>, <a href="#SP45">§45</a>, 3/tp (<a href="3-tp.html#SP12_3">§12.3</a>), 3/rgn (<a href="3-rgn.html#SP18">§18</a>), 3/tm (<a href="3-tm.html#SP37_6">§37.6</a>, <a href="3-tm.html#SP37_7">§37.7</a>).</p>
|
|
|
|
<p class="endnote">The function PL::Spatial::set_progenitor is used in <a href="#SP32_3">§32.3</a>, 3/tm (<a href="3-tm.html#SP37_7">§37.7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP31"></a><b>§31. </b>This is used for error recovery only.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::void_progenitor</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">of</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">spatial_plugin</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"spatial plugin inactive"</span><span class="plain">);</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">of</span><span class="plain">)-</span><span class="element">>progenitor</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">of</span><span class="plain">)-</span><span class="element">>progenitor_set_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::void_progenitor is used in <a href="#SP38_2">§38.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32"></a><b>§32. </b>We need to establish what the rooms are before we worry about objects which
|
|
are "here"; rooms are never "here", so there's no circularity in that,
|
|
and we solve this problem by determining the kind of non-here objects before
|
|
the kind of here-objects.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_stage_II</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Set the here flag for all those objects whose parentage is only thus known</span> <span class="cwebmacronumber">32.1</span>><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>here_flag</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Position this object spatially</span> <span class="cwebmacronumber">32.3</span>><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>here_flag</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Position this object spatially</span> <span class="cwebmacronumber">32.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Issue problem messages if non-physical objects are spatially enclosed</span> <span class="cwebmacronumber">32.2</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 PL::Spatial::spatial_stage_II is used in <a href="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_1"></a><b>§32.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Set the here flag for all those objects whose parentage is only thus known</span> <span class="cwebmacronumber">32.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>here_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">PARENTAGE_HERE_INF</span><span class="plain">)</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>here_flag</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32">§32</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_2"></a><b>§32.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue problem messages if non-physical objects are spatially enclosed</span> <span class="cwebmacronumber">32.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_thing</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Regions::object_is_a_region</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">Instances::get_creating_sentence</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(2, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(3, </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NonThingInModel</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"In the sentence %1, you create an object '%2' which you then seem "</span>
|
|
<span class="string">"to place in or on or as part of '%3', but the kind of '%2' is %4. "</span>
|
|
<span class="string">"Since %4 is not a kind of thing, it follows that %2 is not a thing, "</span>
|
|
<span class="string">"so it doesn't represent something physical and can't be put in spatial "</span>
|
|
<span class="string">"relationships like this. (For the same reason that you can't put "</span>
|
|
<span class="string">"'southeast', the direction, inside a kitchen cupboard.)"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32">§32</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_3"></a><b>§32.3. </b>At last we come to it: determining the progenitor, and part-flag, for the
|
|
object under investigation.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Position this object spatially</span> <span class="cwebmacronumber">32.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">parent_setting_inference</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Find the inference which will decide the progenitor</span> <span class="cwebmacronumber">32.3.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parent_setting_inference</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">whereabouts</span><span class="plain"> =</span>
|
|
<span class="identifier">World::Inferences::get_reference_as_object</span><span class="plain">(</span><span class="identifier">parent_setting_inference</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>here_flag</span><span class="plain">) </span><<span class="cwebmacro">Find the whereabouts of something here</span> <span class="cwebmacronumber">32.3.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">whereabouts</span><span class="plain">) {</span>
|
|
<span class="functiontext">PL::Spatial::set_progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">whereabouts</span><span class="plain">, </span><span class="identifier">parent_setting_inference</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">OBJECT_TREE</span><span class="plain">, </span><span class="string">"Progenitor of $O is $O\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">whereabouts</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<<span class="cwebmacro">Determine whether the object in question is a component part</span> <span class="cwebmacronumber">32.3.3</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32">§32</a> (twice).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_3_1"></a><b>§32.3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Find the inference which will decide the progenitor</span> <span class="cwebmacronumber">32.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">PARENTAGE_NOWHERE_INF</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Make this the determining inference</span> <span class="cwebmacronumber">32.3.1.1</span>><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">PARENTAGE_HERE_INF</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Make this the determining inference</span> <span class="cwebmacronumber">32.3.1.1</span>><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">PARENTAGE_INF</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Make this the determining inference</span> <span class="cwebmacronumber">32.3.1.1</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32_3">§32.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_3_1_1"></a><b>§32.3.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make this the determining inference</span> <span class="cwebmacronumber">32.3.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parent_setting_inference</span><span class="plain">) {</span>
|
|
<span class="identifier">Problems::Issue::contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DuplicateParentage</span><span class="plain">),</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">parent_setting_inference</span><span class="plain">),</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"can only be given its position once"</span><span class="plain">,</span>
|
|
<span class="string">"in a single assertion sentence."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">parent_setting_inference</span><span class="plain"> = </span><span class="identifier">inf</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32_3_1">§32.3.1</a> (three times).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_3_2"></a><b>§32.3.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Find the whereabouts of something here</span> <span class="cwebmacronumber">32.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">whereabouts</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">whereabouts</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">whereabouts</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">here_sentence</span><span class="plain"> =</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">parent_setting_inference</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Set the whereabouts to the last discussed room prior to this inference being drawn</span> <span class="cwebmacronumber">32.3.2.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">whereabouts</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">here_sentence</span><span class="plain">;</span>
|
|
<span class="identifier">Problems::Issue::object_problem_at_sentence</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NoHere</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"was described as being 'here', and there doesn't seem to be any "</span>
|
|
<span class="string">"location being talked about at this point in the source text"</span><span class="plain">,</span>
|
|
<span class="string">"so there's nowhere you can call 'here'."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32_3">§32.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_3_2_1"></a><b>§32.3.2.1. </b>This runs through the source text from the beginning up to the "here"
|
|
sentence, setting <code class="display"><span class="extract">whereabouts</span></code> to any rooms it finds along the way, so that
|
|
when it finishes this will be set to the most recently mentioned.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Set the whereabouts to the last discussed room prior to this inference being drawn</span> <span class="cwebmacronumber">32.3.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">ParseTree::traverse_up_to_ip</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">here_sentence</span><span class="plain">, </span><span class="functiontext">PL::Spatial::seek_room</span><span class="plain">, &</span><span class="identifier">whereabouts</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32_3_2">§32.3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32_3_3"></a><b>§32.3.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Determine whether the object in question is a component part</span> <span class="cwebmacronumber">32.3.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">PART_OF_INF</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) || (</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">))) {</span>
|
|
<span class="identifier">Problems::Issue::object_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RoomOrDoorAsPart</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"was set up as being part of something else, which doors and rooms "</span>
|
|
<span class="string">"are not allowed to be"</span><span class="plain">,</span>
|
|
<span class="string">"because they are part of the fixed map of the world - if they were "</span>
|
|
<span class="string">"parts of something else, they might move around. (Of course, it's "</span>
|
|
<span class="string">"easy to make a door look as if it's part of something to the player - "</span>
|
|
<span class="string">"describing it as part of a wall, or bulkhead, or cottage, say - "</span>
|
|
<span class="string">"and if there really is an entrance that needs to move around - say, "</span>
|
|
<span class="string">"the hatchway on a tank - it's probably best to make it an enterable "</span>
|
|
<span class="string">"container.)"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP32_3">§32.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33"></a><b>§33. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::seek_room</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">sent</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> **</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">isub</span><span class="plain"> = </span><span class="identifier">ParseTree::get_interpretation_of_subject</span><span class="plain">(</span><span class="identifier">sent</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">sub</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">isub</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">sub</span><span class="plain">)) *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">sub</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::seek_room is used in <a href="#SP32_3_2_1">§32.3.2.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP34"></a><b>§34. Completing the model, stages III and IV. </b>By the beginning of Stage III, the progenitor of every object is known, and
|
|
so is whether it is a part. It's time to start work on compiling the I6
|
|
representation of all this, but unfortunately that will need to be quite a
|
|
bit more complicated. So we're going to do this in two stages, the first
|
|
of which is to construct a pair of object trees as an intermediate state.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We have a main object tree, in fact a forest (i.e., it's probably disconnected),
|
|
to represent containment, support, carrying and wearing; and a secondary tree
|
|
for incorporation only. In this source code, we'll use the language of family
|
|
trees (parent, children, siblings) rather than horticulture (branches, leaves,
|
|
grafting). Both trees must be well-founded, and must be such that each object
|
|
is the parent of all its children. But the trees aren't independent of each
|
|
other: an object is not allowed to have a parent in both trees at once.
|
|
If it has a parent in either one, then that parent is required to be its progenitor.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP35"></a><b>§35. </b>The following logs the more interesting tree:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::log_object_tree</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_parent</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::log_object_tree_recursively</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, 0);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::log_object_tree_recursively</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">depth</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">>0) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">" "</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">--; }</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$O\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::log_object_tree_recursively</span><span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::log_object_tree_recursively</span><span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::log_object_tree is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="endnote">The function PL::Spatial::log_object_tree_recursively appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36"></a><b>§36. </b>The initial state of both trees is total disconnection. They are then produced
|
|
using only two operations, which we'll call "adoption" and "parting".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The adoption routine is the equivalent of the Inform 6 statement "move
|
|
X to Y", and moves X and its children to become the youngest child of Y.
|
|
The tree is grown entirely from its root by repeated use of this one operation.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::adopt_object</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">orphan</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">foster</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">OBJECT_TREE</span><span class="plain">, </span><span class="string">"Grafting $O to be child of $O\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">, </span><span class="identifier">foster</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">orphan</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">"orphan is null in adoption"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">foster</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">"foster is null in adoption"</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">former_parent</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_parent</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">former_parent</span><span class="plain">) </span><<span class="cwebmacro">Remove the object from the main object tree</span> <span class="cwebmacronumber">36.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Adopt the object into the main object tree</span> <span class="cwebmacronumber">36.3</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::adopt_object is used in <a href="#SP38_3">§38.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36_1"></a><b>§36.1. </b>"Parting" is the operation of being removed from the main tree and placed
|
|
in the incorporation tree instead, but with the same parent.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::part_object</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">orphan</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">OBJECT_TREE</span><span class="plain">, </span><span class="string">"Parting $O\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">orphan</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">"new part is null in parting"</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">former_parent</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_parent</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">former_parent</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">"new part is without parent"</span><span class="plain">);</span>
|
|
|
|
<<span class="cwebmacro">Remove the object from the main object tree</span> <span class="cwebmacronumber">36.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Adopt the object into the incorporation tree</span> <span class="cwebmacronumber">36.1.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::part_object is used in <a href="#SP38_3">§38.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36_2"></a><b>§36.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Remove the object from the main object tree</span> <span class="cwebmacronumber">36.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">former_parent</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain"> == </span><span class="identifier">orphan</span><span class="plain">) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">former_parent</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain"> =</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">elder</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">former_parent</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">elder</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">elder</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain"> == </span><span class="identifier">orphan</span><span class="plain">)</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">elder</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain"> =</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">;</span>
|
|
<span class="identifier">elder</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">elder</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_parent</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_sibling</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="#SP36">§36</a>, <a href="#SP36_1">§36.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36_3"></a><b>§36.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Adopt the object into the main object tree</span> <span class="cwebmacronumber">36.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">foster</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">foster</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain"> = </span><span class="identifier">orphan</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">elder</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">foster</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">elder</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">)</span>
|
|
<span class="identifier">elder</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">elder</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">elder</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain"> = </span><span class="identifier">orphan</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>object_tree_parent</span><span class="plain"> = </span><span class="identifier">foster</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP36">§36</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36_1_1"></a><b>§36.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Adopt the object into the incorporation tree</span> <span class="cwebmacronumber">36.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">former_parent</span><span class="plain">)-</span><span class="element">>incorp_tree_child</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">former_parent</span><span class="plain">)-</span><span class="element">>incorp_tree_child</span><span class="plain"> = </span><span class="identifier">orphan</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">existing_part</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">former_parent</span><span class="plain">)-</span><span class="element">>incorp_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">existing_part</span><span class="plain">)-</span><span class="element">>incorp_tree_sibling</span><span class="plain">)</span>
|
|
<span class="identifier">existing_part</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">existing_part</span><span class="plain">)-</span><span class="element">>incorp_tree_sibling</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">existing_part</span><span class="plain">)-</span><span class="element">>incorp_tree_sibling</span><span class="plain"> = </span><span class="identifier">orphan</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">orphan</span><span class="plain">)-</span><span class="element">>incorp_tree_parent</span><span class="plain"> = </span><span class="identifier">former_parent</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP36_1">§36.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37"></a><b>§37. </b>What will we use the trees for? Well, one use is to tell other plugins
|
|
which depend on Spatial whether or not one object spatially contains another:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::encloses</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I1</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I2</span><span class="plain">) {</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">I1</span><span class="plain">) {</span>
|
|
<span class="identifier">I1</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I1</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I1</span><span class="plain"> == </span><span class="identifier">I2</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="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 PL::Spatial::encloses is used in 3/rgn (<a href="3-rgn.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38"></a><b>§38. </b>But the main use for the trees is, as noted above, to form a convenient
|
|
intermediate state between the mass of progenitor data and the messy Inform 6
|
|
code it turns into. Here goes:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_stage_III</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">well_founded</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Define the Rucksack Class constant</span> <span class="cwebmacronumber">38.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Check the well-foundedness of the hierarchy of the set of progenitors</span> <span class="cwebmacronumber">38.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">well_founded</span><span class="plain">) </span><<span class="cwebmacro">Expand the progenitor data into the two object trees</span> <span class="cwebmacronumber">38.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert the portability of any item carried or supported by a person</span> <span class="cwebmacronumber">38.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert I6-level properties to express the spatial structure</span> <span class="cwebmacronumber">38.5</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Set up the compilation sequence so that it traverses the main object tree</span> <span class="cwebmacronumber">38.6</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Log::aspect_switched_on</span><span class="plain">(</span><span class="identifier">OBJECT_TREE_DA</span><span class="plain">)) </span><span class="functiontext">PL::Spatial::log_object_tree</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 PL::Spatial::spatial_stage_III is used in <a href="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_1"></a><b>§38.1. </b>To enable the use of player's holdalls, we must declare a constant
|
|
<code class="display"><span class="extract">RUCKSACK_CLASS</span></code> to tell some code in the template layer to use possessions
|
|
with this I6 class as the rucksack pro tem. This is all a bit of a hack, to retrofit
|
|
a degree of generality onto the original I6 library feature, and even then
|
|
it isn't really fully general: only the player has the benefit of a "player's
|
|
holdall" (hence the name), with other actors oblivious.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Define the Rucksack Class constant</span> <span class="cwebmacronumber">38.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_players_holdall</span><span class="plain">) {</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">RUCKSACK_CLASS_HL</span><span class="plain">);</span>
|
|
<span class="identifier">Hierarchy::make_available</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::named_iname_constant</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">K_players_holdall</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_2"></a><b>§38.2. </b>The following verifies, in a brute-force way, that there are no cycles in
|
|
the directed graph formed by the objects and progeniture. (We're doing this
|
|
now, rather than at Stage II above, because other plugins may also have
|
|
changed progenitors at Stage II.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Check the well-foundedness of the hierarchy of the set of progenitors</span> <span class="cwebmacronumber">38.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">max_loop</span><span class="plain"> = </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain">) + 1;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I2</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">I2</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">k</span><span class="plain">=0; (</span><span class="identifier">I2</span><span class="plain">) && (</span><span class="identifier">k</span><span class="plain"><</span><span class="identifier">max_loop</span><span class="plain">);</span>
|
|
<span class="identifier">I2</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I2</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">I2</span><span class="plain"> == </span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Diagnose the ill-foundedness with a problem message</span> <span class="cwebmacronumber">38.2.1</span>><span class="plain">;</span>
|
|
<span class="functiontext">PL::Spatial::void_progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">); </span> <span class="comment">thus cutting the cycle</span>
|
|
<span class="identifier">well_founded</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_2_1"></a><b>§38.2.1. </b>The cutest of all the object problem messages, really:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Diagnose the ill-foundedness with a problem message</span> <span class="cwebmacronumber">38.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(1, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_IllFounded</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"The %1 seems to be containing itself: "</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I3</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">TRUE</span><span class="plain">) {</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">IW</span><span class="plain"> = </span><span class="identifier">Instances::get_name</span><span class="plain">(</span><span class="identifier">I3</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">creator</span><span class="plain"> = </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">IW</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(2, </span><span class="identifier">I3</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(3, </span><span class="identifier">creator</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"%2 (created by %3) "</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I3</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain">) </span><span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"part of "</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"in "</span><span class="plain">);</span>
|
|
<span class="identifier">I3</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I3</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I3</span><span class="plain"> == </span><span class="identifier">I</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"%1... and so on. This is forbidden."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38_2">§38.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_3"></a><b>§38.3. </b>Intermediate states are always suspect in program design, and we might
|
|
ask what's wrong with simply making the trees as we go along, rather than
|
|
storing all of those progenitors and then converting them into the trees.
|
|
We don't do that because (for reasons to do with "here" and with how work
|
|
is shared among the plugins) the progenitors are determined in an undefined
|
|
order; if we made the object tree as we went along, the spatial model would
|
|
be perfectly correct, but siblings — say, the three things on the grass in
|
|
the Croquet Lawn — would be compiled in the I6 code in some undefined
|
|
order. This order matters because it affects the text produced by typical
|
|
room descriptions: "You can also see a box, a ball and a peg here." might
|
|
become "You can also see a ball, a box and a peg here."
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Inform therefore needs a definite rule of ordering, and this rule is that
|
|
siblings appear in their order of creation in the I7 source text, with the
|
|
first created being the eldest child. Looping over the objects to add them
|
|
to the trees in creation order achieves this nicely:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Expand the progenitor data into the two object trees</span> <span class="cwebmacronumber">38.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">))</span>
|
|
<span class="functiontext">PL::Spatial::adopt_object</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::part_object</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_4"></a><b>§38.4. </b>As a brief aside: if something is carried by a living person, we can
|
|
reasonably assume it's portable. (This is needed in particular to ensure that
|
|
supporters which are initially carried don't pick up "fixed in place" in
|
|
the absence of other information.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert the portability of any item carried or supported by a person</span> <span class="cwebmacronumber">38.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">portable</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">J</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">J</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">); </span><span class="identifier">J</span><span class="plain">; </span><span class="identifier">J</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">J</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">J</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">J</span><span class="plain">, </span><span class="identifier">K_person</span><span class="plain">)) {</span>
|
|
<span class="identifier">portable</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">portable</span><span class="plain">)</span>
|
|
<span class="identifier">Properties::EitherOr::assert</span><span class="plain">(</span>
|
|
<span class="identifier">P_fixed_in_place</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_5"></a><b>§38.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Assert I6-level properties to express the spatial structure</span> <span class="cwebmacronumber">38.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<<span class="cwebmacro">Assert an explicit default description value for the room kind</span> <span class="cwebmacronumber">38.5.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert room and thing indicator properties</span> <span class="cwebmacronumber">38.5.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert container and supporter indicator properties</span> <span class="cwebmacronumber">38.5.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert incorporation tree properties</span> <span class="cwebmacronumber">38.5.4</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_5_1"></a><b>§38.5.1. </b>We need to make sure that every room does have an I6 <code class="display"><span class="extract">description</span></code> value
|
|
which can be written to (i.e., we need to avoid accidental use of the Z-machine's
|
|
readable-only default properties feature); hence the following, which ensures
|
|
that any room with no explicit description will inherit <code class="display"><span class="extract">EMPTY_TEXT_VALUE</span></code>
|
|
as a value for <code class="display"><span class="extract">description</span></code> from the room class.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert an explicit default description value for the room kind</span> <span class="cwebmacronumber">38.5.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_room</span><span class="plain">) {</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">desc_seen</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_room</span><span class="plain">), </span><span class="identifier">PROPERTY_INF</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">P_description</span><span class="plain">)</span>
|
|
<span class="identifier">desc_seen</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">desc_seen</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="string">"\</span><span class="plain">"</span><span class="string">\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_description</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_room</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_unescaped_wording</span><span class="plain">(</span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)), </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38_5">§38.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_5_2"></a><b>§38.5.2. </b>These I6-only properties exist for speed. They're implemented in I6 as
|
|
attributes, which means that testing them is very fast and there is no memory
|
|
overhead for their storage. That shaves a little time off route-finding in
|
|
extensive maps.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert room and thing indicator properties</span> <span class="cwebmacronumber">38.5.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">P_mark_as_room</span><span class="plain"> = </span><span class="identifier">Properties::EitherOr::new_nameless</span><span class="plain">(</span><span class="identifier">L</span><span class="string">"mark_as_room"</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::EitherOr::implement_as_attribute</span><span class="plain">(</span><span class="identifier">P_mark_as_room</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">P_mark_as_thing</span><span class="plain"> = </span><span class="identifier">Properties::EitherOr::new_nameless</span><span class="plain">(</span><span class="identifier">L</span><span class="string">"mark_as_thing"</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::EitherOr::implement_as_attribute</span><span class="plain">(</span><span class="identifier">P_mark_as_thing</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">))</span>
|
|
<span class="identifier">Properties::EitherOr::assert</span><span class="plain">(</span>
|
|
<span class="identifier">P_mark_as_room</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_thing</span><span class="plain">))</span>
|
|
<span class="identifier">Properties::EitherOr::assert</span><span class="plain">(</span>
|
|
<span class="identifier">P_mark_as_thing</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38_5">§38.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_5_3"></a><b>§38.5.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Assert container and supporter indicator properties</span> <span class="cwebmacronumber">38.5.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">P_container</span><span class="plain"> = </span><span class="identifier">Properties::EitherOr::new_nameless</span><span class="plain">(</span><span class="identifier">L</span><span class="string">"container"</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::EitherOr::implement_as_attribute</span><span class="plain">(</span><span class="identifier">P_container</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">P_supporter</span><span class="plain"> = </span><span class="identifier">Properties::EitherOr::new_nameless</span><span class="plain">(</span><span class="identifier">L</span><span class="string">"supporter"</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::EitherOr::implement_as_attribute</span><span class="plain">(</span><span class="identifier">P_supporter</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_container</span><span class="plain">))</span>
|
|
<span class="identifier">Properties::EitherOr::assert</span><span class="plain">(</span>
|
|
<span class="identifier">P_container</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_supporter</span><span class="plain">))</span>
|
|
<span class="identifier">Properties::EitherOr::assert</span><span class="plain">(</span>
|
|
<span class="identifier">P_supporter</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38_5">§38.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_5_4"></a><b>§38.5.4. </b>The main spatial tree is expressed in the compiled I6 code in an implicit
|
|
way, using the I6 object tree, but the incorporation tree is expressed using
|
|
a triplet of I6-only properties:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert incorporation tree properties</span> <span class="cwebmacronumber">38.5.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">P_component_parent</span><span class="plain"> =</span>
|
|
<span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"component_parent"</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
|
|
<span class="identifier">P_component_child</span><span class="plain"> =</span>
|
|
<span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"component_child"</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
|
|
<span class="identifier">P_component_sibling</span><span class="plain"> =</span>
|
|
<span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"component_sibling"</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_thing</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">nothing_constant</span><span class="plain"> = </span><span class="identifier">Rvalues::new_nothing_object_constant</span><span class="plain">();</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_component_parent</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_thing</span><span class="plain">),</span>
|
|
<span class="identifier">nothing_constant</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_component_child</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_thing</span><span class="plain">),</span>
|
|
<span class="identifier">nothing_constant</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_component_sibling</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_thing</span><span class="plain">),</span>
|
|
<span class="identifier">nothing_constant</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>incorp_tree_parent</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cp</span><span class="plain">) </span><span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_component_parent</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">cp</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">cc</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>incorp_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc</span><span class="plain">) </span><span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_component_child</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">cc</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">cs</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>incorp_tree_sibling</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cs</span><span class="plain">) </span><span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_component_sibling</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38_5">§38.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38_6"></a><b>§38.6. </b>Because Inform 6 requires objects to be defined in a traversal order for
|
|
the main spatial tree (only the main one because I6 has no concept of
|
|
incorporation), we use the main tree to determine the compilation sequence
|
|
for objects:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Set up the compilation sequence so that it traverses the main object tree</span> <span class="cwebmacronumber">38.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Instances::begin_sequencing_objects</span><span class="plain">();</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_parent</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::add_to_object_sequence</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, 0);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP38">§38</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP39"></a><b>§39. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::add_to_object_sequence</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain">) {</span>
|
|
<span class="identifier">Instances::place_this_object_next</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>I6_definition_depth</span><span class="plain"> = </span><span class="identifier">depth</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::add_to_object_sequence</span><span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">)</span>
|
|
<span class="functiontext">PL::Spatial::add_to_object_sequence</span><span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::add_to_object_sequence is used in <a href="#SP38_6">§38.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP40"></a><b>§40. </b>The "definition depth" is the same thing as the depth in the main tree;
|
|
0 for a room, 1 for a player standing in that room, 2 for his hat, and so on.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::get_definition_depth</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">spatial_plugin</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>I6_definition_depth</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> 0;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::get_definition_depth appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP41"></a><b>§41. </b>At last, Stage IV. We're all done except for a little checking of the
|
|
degenerate case where Inform is just binding up an existing story file, so
|
|
that there's really no spatial model at all — the world is, or should be,
|
|
empty.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_stage_IV</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Task::wraps_existing_storyfile</span><span class="plain">()) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::Issue::unlocated_problem</span><span class="plain">(</span><span class="identifier">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RoomInIgnoredSource</span><span class="plain">),</span>
|
|
<span class="string">"This is supposed to be a source text which only contains "</span>
|
|
<span class="string">"release instructions to bind up an existing story file "</span>
|
|
<span class="string">"(for instance, one produced using Inform 6). That's because "</span>
|
|
<span class="string">"the instruction 'Release along with an existing story file' "</span>
|
|
<span class="string">"is present. So the source text must not contain rooms or "</span>
|
|
<span class="string">"other game design - these would be ignored."</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</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 PL::Spatial::spatial_stage_IV is used in <a href="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP42"></a><b>§42. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::index_spatial_relationship</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">rel</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">) {</span>
|
|
<span class="comment">we could set <code class="display"><span class="extract">rel</span></code> to "in" here, but the index omits that for clarity</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">K_supporter</span><span class="plain">)) </span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"on"</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">K_person</span><span class="plain">)) </span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"carried"</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain">) </span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"part"</span><span class="plain">;</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">PROPERTY_INF</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">P_worn</span><span class="plain">)</span>
|
|
<span class="identifier">rel</span><span class="plain"> = </span><span class="string">"worn"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rel</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>%s</i> "</span><span class="plain">, </span><span class="identifier">rel</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::index_spatial_relationship appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP43"></a><b>§43. </b>If something is a part, we don't detail it on the World index page, since
|
|
it already turns up under its owner.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::no_detail_index</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>incorp_tree_parent</span><span class="plain"> != </span><span class="identifier">NULL</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 PL::Spatial::no_detail_index appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP44"></a><b>§44. </b>In the World index, we recurse to show the contents and parts:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Spatial::index_object_further</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">details</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">depth</span><span class="plain"> > </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain">) + 1) </span><span class="reserved">return</span><span class="plain">; </span> <span class="comment">to recover from errors</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>incorp_tree_child</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I2</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>incorp_tree_child</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">I2</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">Data::Objects::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I2</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">details</span><span class="plain">);</span>
|
|
<span class="identifier">I2</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I2</span><span class="plain">)-</span><span class="element">>incorp_tree_sibling</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">)</span>
|
|
<span class="identifier">Data::Objects::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_child</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">details</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I2</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I2</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I2</span><span class="plain">)) && (</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I2</span><span class="plain">) != </span><span class="identifier">I</span><span class="plain">)) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="functiontext">PL::Map::get_door_data</span><span class="plain">(</span><span class="identifier">I2</span><span class="plain">, &</span><span class="identifier">A</span><span class="plain">, &</span><span class="identifier">B</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain"> == </span><span class="identifier">I</span><span class="plain">) </span><span class="identifier">Data::Objects::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I2</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">details</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">B</span><span class="plain"> == </span><span class="identifier">I</span><span class="plain">) </span><span class="identifier">Data::Objects::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I2</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">details</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">PL::Player::index_object_further</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">details</span><span class="plain">);</span>
|
|
<span class="functiontext">PL::Backdrops::index_object_further</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">details</span><span class="plain">, 0);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">)</span>
|
|
<span class="identifier">Data::Objects::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>object_tree_sibling</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">details</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Spatial::index_object_further appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP45"></a><b>§45. </b>And also:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Spatial::spatial_add_to_World_index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">O</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">O</span><span class="plain">) && (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">, </span><span class="identifier">K_thing</span><span class="plain">))) {</span>
|
|
<span class="identifier">HTMLFiles::open_para</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 1, </span><span class="string">"tight"</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>initial location:</i> "</span><span class="plain">);</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"in"</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">K_supporter</span><span class="plain">)) </span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"on"</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">K_person</span><span class="plain">)) </span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"carried by"</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">O</span><span class="plain">)-</span><span class="element">>part_flag</span><span class="plain">) </span><span class="identifier">rel</span><span class="plain"> = </span><span class="string">"part of"</span><span class="plain">;</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">), </span><span class="identifier">PROPERTY_INF</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">P_worn</span><span class="plain">)</span>
|
|
<span class="identifier">rel</span><span class="plain"> = </span><span class="string">"worn by"</span><span class="plain">;</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%s "</span><span class="plain">, </span><span class="identifier">rel</span><span class="plain">);</span>
|
|
<span class="identifier">Instances::index_name</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">at</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">spatial</span><span class="plain">, </span><span class="identifier">O</span><span class="plain">)-</span><span class="element">>progenitor_set_at</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">at</span><span class="plain">) </span><span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">at</span><span class="plain">)));</span>
|
|
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</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 PL::Spatial::spatial_add_to_World_index is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="3-tnt.html">Back to 'The Naming Thicket'</a></li><li><a href="3-sr.html">Continue with 'Spatial Relations'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|