mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
477 lines
66 KiB
HTML
477 lines
66 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Name Resolution</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<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="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../compiler.html">compiler tools</a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul><h2>Compiler Webs</h2><ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul><h2>Inbuild Modules</h2><ul>
|
|
<li><a href="../supervisor-module/index.html">supervisor</a></li>
|
|
</ul><h2>Inform7 Modules</h2><ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="index.html"><span class="selectedlink">assertions</span></a></li>
|
|
<li><a href="../values-module/index.html">values</a></li>
|
|
<li><a href="../knowledge-module/index.html">knowledge</a></li>
|
|
<li><a href="../imperative-module/index.html">imperative</a></li>
|
|
<li><a href="../runtime-module/index.html">runtime</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="../bytecode-module/index.html">bytecode</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul><h2>Services</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../calculus-module/index.html">calculus</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Name Resolution' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#4">Chapter 4: Assertions</a></li><li><b>Name Resolution</b></li></ul></div>
|
|
<p class="purpose">To resolve abbreviated or ambiguous nouns in context of their headings.</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. </b>Every heading must carry with it a linked list of the nouns created in
|
|
sentences which belong to it. So when any noun is created, the following
|
|
is called to let the current sentence's heading know that it has a new
|
|
friend.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">name_resolution_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heading_count</span><span class="plain-syntax">; </span><span class="comment-syntax"> used when tallying up objects under their headings</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_under_heading</span><span class="plain-syntax">; </span><span class="comment-syntax"> next in the list under that</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">search_score</span><span class="plain-syntax">; </span><span class="comment-syntax"> used when searching nametags to parse names</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_to_search</span><span class="plain-syntax">; </span><span class="comment-syntax"> similarly</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">name_resolution_data</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure name_resolution_data is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b></p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_NOUNS_UNDER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">=</span><span class="identifier-syntax">h</span><span class="plain-syntax">-></span><span class="identifier-syntax">list_of_contents</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">=</span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">next_under_heading</span><span class="plain-syntax">)</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">name_resolution_data</span><span class="plain-syntax"> *</span><span class="function-syntax">NameResolution::data</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">NameResolution::data</span></span>:<br/><a href="4-nr.html#SP4">§4</a>, <a href="4-nr.html#SP6">§6</a>, <a href="4-nr.html#SP10_1">§10.1</a>, <a href="4-nr.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to fetch resolution data for null tag"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> &(</span><span class="identifier-syntax">t</span><span class="plain-syntax">-></span><span class="identifier-syntax">name_resolution</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::initialise</span><span class="plain-syntax">(</span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to initialise resolution data for null tag"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP7" class="function-link"><span class="function-syntax">NameResolution::disturb</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::attach_noun</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP4" class="function-link"><span class="function-syntax">NameResolution::verify_divisions</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_tags_attached</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::attach_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_tag</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Headings::of_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">no_tags_attached</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">name_resolution_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nrd</span><span class="plain-syntax"> = </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_tag</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nrd</span><span class="plain-syntax">-></span><span class="element-syntax">next_to_search</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-></span><span class="identifier-syntax">last_in_list_of_contents</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">h</span><span class="plain-syntax">-></span><span class="identifier-syntax">list_of_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_tag</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-></span><span class="identifier-syntax">last_in_list_of_contents</span><span class="plain-syntax">)-></span><span class="element-syntax">next_under_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_tag</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nrd</span><span class="plain-syntax">-></span><span class="element-syntax">next_under_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-></span><span class="identifier-syntax">last_in_list_of_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_tag</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>The following verification checks that every noun is listed
|
|
in the list for exactly one heading. The point of the check is not so much
|
|
to make sure the tag lists are properly formed, as the code making those
|
|
is pretty elementary: it's really a test that the source text is well-formed
|
|
with everything placed under a heading, and no sentence having fallen
|
|
through a crack.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::verify_divisions</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">NameResolution::verify_divisions</span></span>:<br/><a href="4-nr.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">; </span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">total</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">disaster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">noun</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">heading_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="identifier-syntax">headings</span><span class="plain-syntax">-></span><span class="identifier-syntax">subordinates</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NOUNS_UNDER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">heading_count</span><span class="plain-syntax">++, </span><span class="identifier-syntax">total</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">noun</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">heading_count</span><span class="plain-syntax"> > </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$z occurs under %d headings\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">heading_count</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">disaster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">total</span><span class="plain-syntax"> != </span><span class="identifier-syntax">no_tags_attached</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d tags != %d attached\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">total</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_tags_attached</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">disaster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">disaster</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error_tree_unsafe</span><span class="plain-syntax">(</span><span class="string-syntax">"heading contents list failed verification"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>Identifying noun phrases is tricky. Many plausible phrases could refer in
|
|
principle to several different instances: "east", for instance, might
|
|
mean the direction or, say, "east garden". And what if the source
|
|
mentions many chairs, and now refers simply to "the chair"? This problem
|
|
is not so acute for nouns referring to abstractions, where we can simply
|
|
forbid duplicate definitions and require an exact wording when talking
|
|
about them. But for names of IF objects — which represent the solid and often
|
|
repetitive items and places of a simulated world — it cannot be ducked.
|
|
We can hardly tell an Inform author to create at most one item whose
|
|
name contains the word "jar", for instance.
|
|
</p>
|
|
|
|
<p class="commentary">All programming languages face similar problems. In C, for instance, a local
|
|
variable named <span class="extract"><span class="extract-syntax">east</span></span> will be recognised in preference to a global one of the
|
|
same name (to some extent external linking provides a third level again).
|
|
The way this is done is usually explained in terms of the "scope" of a
|
|
definition, the part of the source for which it is valid: the winner, in
|
|
cases of ambiguity, being the definition of narrowest scope which is valid
|
|
at the position in question. In our terms, a stand-alone C program has a
|
|
heading tree like so, with two semantically meaningful heading levels,
|
|
File (0) and Routine (1), and then sublevels provided by braced blocks:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> File</span>
|
|
<span class="plain-syntax"> main()</span>
|
|
<span class="plain-syntax"> routine1()</span>
|
|
<span class="plain-syntax"> interior block of a loop</span>
|
|
<span class="plain-syntax"> ...</span>
|
|
<span class="plain-syntax"> routine2()</span>
|
|
<span class="plain-syntax"> ...</span>
|
|
</pre>
|
|
<p class="commentary">The resolution of a name at a given position P is unambiguous: find the
|
|
heading H to which P belongs; if the name is defined there, accept that;
|
|
if not move H upwards and try again; if it is not defined even at File (0)
|
|
level, issue an error: the term is undefined.
|
|
</p>
|
|
|
|
<p class="commentary">Inform is different in two respects, one trivial, the other not. The trivial
|
|
difference is that an Inform name can be defined midway through the matter
|
|
(though as a result of the PM_ revision, ANSI C now also allows variables
|
|
to be created mid-block, in fact: and some C compilers even implement this).
|
|
</p>
|
|
|
|
<p class="commentary">The big difference is that in Inform, names are always visible across
|
|
headings. They can be used before being defined; Section 2 of Part II is
|
|
free to mention the elephant defined in Section 7 of Part VIII, say.
|
|
English text is like this: a typical essay has one great big namespace.
|
|
</p>
|
|
|
|
<p class="commentary">We resolve this by searching backwards through recent noun creations in
|
|
the current heading, then in the current heading level above that, and so
|
|
on up to the top conceptual level of the source. Thus a "chair" in the
|
|
current chapter will always have priority over any in previous chapters,
|
|
and so on. However, kinds are always given priority over mere instances,
|
|
in order that "door" will retain its generic meaning even if, say,
|
|
"an oak door" is created.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>This means that, under every heading, the search sequence is different.
|
|
So for the sake of efficiency we construct a linked list of world
|
|
objects in priority order the first time we search under a new heading,
|
|
then simply use that thereafter: we also keep track of the tail of this
|
|
list. Sections other than this one cannot read the list itself, and
|
|
use the following definition to iterate through it.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_NT_SEARCH_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt_search_start</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">next_to_search</span><span class="plain-syntax">)</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt_search_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">nt_search_finish</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>The search sequence is, in effect, a cache storing a former computation,
|
|
and like all caches it can fall out of date if the circumstances change so
|
|
that the same computation would now produce a different outcome. That can
|
|
only happen here if a new noun is to be created: the assertion-maker
|
|
calls the following routine to let us know.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">noun_search_list_valid_for_this_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> initially it's unbuilt</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::disturb</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">NameResolution::disturb</span></span>:<br/><a href="4-nr.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun_search_list_valid_for_this_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>The headings and subheadings are formed into a tree in which each heading
|
|
contains its lesser-order headings. The pseudo-heading exists to be the root
|
|
of this tree; the entire text falls under it. It is not a real heading at all,
|
|
and has no "level" or "indentation" as such.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::make_the_tree</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">NameResolution::make_the_tree</span></span>:<br/><a href="4-nr.html#SP9_3">§9.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Headings::assemble_tree</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">NameResolution::pseudo_heading</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">NameResolution::pseudo_heading</span></span>:<br/><a href="4-nr.html#SP9_2">§9.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Headings::root_of_tree</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">()-></span><span class="identifier-syntax">headings</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b>Leaving aside the cache, then, we build a list as initially empty, then
|
|
all nametags of priority 1 as found by recursively searching headings, then all
|
|
nametags of priority 2, and so on.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::construct_noun_search_list</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">NameResolution::construct_noun_search_list</span></span>:<br/><a href="4-nr.html#SP12">§12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-nr.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Work out the heading from which we wish to search</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">noun_search_list_valid_for_this_heading</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> rely on the cache</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">HEADINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Rebuilding noun search list from: $H\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-nr.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Start the search list empty</span><span class="named-paragraph-number">9.2</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP10" class="function-link"><span class="function-syntax">NameResolution::build_search_list_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP10" class="function-link"><span class="function-syntax">NameResolution::build_search_list_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PROPER_NOUN</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-nr.html#SP9_3" class="named-paragraph-link"><span class="named-paragraph">Verify that the search list indeed contains every noun just once</span><span class="named-paragraph-number">9.3</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun_search_list_valid_for_this_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>§9.1. </b>Basically, we calculate the search list from the point of view of the
|
|
current sentence:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out the heading from which we wish to search</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">))))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"cannot establish position P: there is no current sentence"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">source_location</span><span class="plain-syntax"> </span><span class="identifier-syntax">position_P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Headings::of_location</span><span class="plain-syntax">(</span><span class="identifier-syntax">position_P</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-nr.html#SP9">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_2" class="paragraph-anchor"></a><b>§9.2. </b>The pseudo-heading has no list of contents because all objects are created in
|
|
source files, each certainly underneath a File (0) heading, so nothing should
|
|
ever get that far.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Start the search list empty</span><span class="named-paragraph-number">9.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt_search_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt_search_finish</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pseud</span><span class="plain-syntax"> = </span><a href="4-nr.html#SP8" class="function-link"><span class="function-syntax">NameResolution::pseudo_heading</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pseud</span><span class="plain-syntax">-></span><span class="identifier-syntax">list_of_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> should always be true, but just in case</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-nr.html#SP9">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_3" class="paragraph-anchor"></a><b>§9.3. </b>The potential for disaster if this algorithm should be incorrect is high,
|
|
so we perform a quick count to see if everything made it onto the list
|
|
and produce an internal error if not.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Verify that the search list indeed contains every noun just once</span><span class="named-paragraph-number">9.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NT_SEARCH_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="identifier-syntax">no_tags_attached</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Reordering failed from $H\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d tags created, %d in ordering\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_tags_attached</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">IndexHeadings::log_all_headings</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Making fresh tree:\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP8" class="function-link"><span class="function-syntax">NameResolution::make_the_tree</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">IndexHeadings::log_all_headings</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error_tree_unsafe</span><span class="plain-syntax">(</span><span class="string-syntax">"reordering of nametags failed"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-nr.html#SP9">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. </b>The following adds all nametags under heading H to the search list, using
|
|
its own list of contents, and then recurses to add all objects under
|
|
subheadings of H other than the one which has just recursed up to H. With
|
|
that done, we recurse up to the superheading of H.
|
|
</p>
|
|
|
|
<p class="commentary">To prove that <a href="4-nr.html#SP10" class="internal">NameResolution::build_search_list_from</a> is called exactly once
|
|
for each heading in the tree, forget about the up/down orientation and consider it
|
|
as a graph instead. At each node we try going to every possible other node,
|
|
except the way we came (at the start of the traverse, the "way we came"
|
|
being null): clearly this ensures that all of our neighbours have been
|
|
visited. Since every heading ultimately depends from the pseudo-heading,
|
|
the graph is connected, and therefore every heading must eventually be
|
|
visited. No heading can be visited twice, because that would mean that a
|
|
cycle of nodes \(H_1, H_2, ..., H_i, H_1\) must exist: since we have a tree
|
|
structure, there are no loops, and so \(H_i = H_2\), \(H_{i-1} = H_3\), and so
|
|
on — we must be walking a path and then retracing our steps in reverse.
|
|
That being so, there is a point where we turned back: we went from \(H_j\) to
|
|
\(H_{j+1}\) to \(H_j\) again. And this violates the principle that at each node
|
|
we move outwards in every direction except the way we came, a
|
|
contradiction.
|
|
</p>
|
|
|
|
<p class="commentary">The routine looks as if it may have a large recursion depth — maybe as
|
|
deep as the number of headings — but because we go downwards and then
|
|
upwards, the maximum recursion depth of the routine is less than \(2L+1\), where
|
|
\(L\) is the number of levels in the tree other than the pseudo-heading. This
|
|
provides an upper bound of about 21, regardless of the size of the source
|
|
text. The running time is linear in both the number of headings and the
|
|
number of nametags in the source text.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::build_search_list_from</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">NameResolution::build_search_list_from</span></span>:<br/><a href="4-nr.html#SP9">§9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">within</span><span class="plain-syntax">, </span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">way_we_came</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">; </span><span class="identifier-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subhead</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">within</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NOUNS_UNDER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">within</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Nouns::subclass</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) == </span><span class="identifier-syntax">p</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-nr.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Add tag to the end of the search list</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> recurse downwards through subordinate headings, other than the way we came up</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subhead</span><span class="plain-syntax"> = </span><span class="identifier-syntax">within</span><span class="plain-syntax">-></span><span class="identifier-syntax">child_heading</span><span class="plain-syntax">; </span><span class="identifier-syntax">subhead</span><span class="plain-syntax">; </span><span class="identifier-syntax">subhead</span><span class="plain-syntax"> = </span><span class="identifier-syntax">subhead</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_heading</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subhead</span><span class="plain-syntax"> != </span><span class="identifier-syntax">way_we_came</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP10" class="function-link"><span class="function-syntax">NameResolution::build_search_list_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subhead</span><span class="plain-syntax">, </span><span class="identifier-syntax">within</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> recurse upwards to superior headings, unless we came here through a downward recursion</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">within</span><span class="plain-syntax">-></span><span class="identifier-syntax">parent_heading</span><span class="plain-syntax"> != </span><span class="identifier-syntax">way_we_came</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP10" class="function-link"><span class="function-syntax">NameResolution::build_search_list_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">within</span><span class="plain-syntax">-></span><span class="identifier-syntax">parent_heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">within</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10_1" class="paragraph-anchor"></a><b>§10.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add tag to the end of the search list</span><span class="named-paragraph-number">10.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt_search_finish</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt_search_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt_search_finish</span><span class="plain-syntax">)-></span><span class="element-syntax">next_to_search</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"end of tag search list has frayed somehow"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt_search_finish</span><span class="plain-syntax">)-></span><span class="element-syntax">next_to_search</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">next_to_search</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt_search_finish</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-nr.html#SP10">§10</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. </b>The search list is used for finding best matches in a particular order, the
|
|
order being used to break tie-breaks. Note that we return <span class="extract"><span class="extract-syntax">NULL</span></span> if no noun
|
|
in the search list has a positive score.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NameResolution::set_noun_search_score</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">NameResolution::set_noun_search_score</span></span>:<br/><a href="4-nr.html#SP12">§12</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">search_score</span><span class="plain-syntax"> = </span><span class="identifier-syntax">v</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="function-syntax">NameResolution::highest_scoring_noun_searched</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">NameResolution::highest_scoring_noun_searched</span></span>:<br/><a href="4-nr.html#SP12">§12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, *</span><span class="identifier-syntax">best_nt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">best_score</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NT_SEARCH_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><a href="4-nr.html#SP3" class="function-link"><span class="function-syntax">NameResolution::data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">)-></span><span class="element-syntax">search_score</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">x</span><span class="plain-syntax"> > </span><span class="identifier-syntax">best_score</span><span class="plain-syntax">) { </span><span class="identifier-syntax">best_nt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_score</span><span class="plain-syntax"> = </span><span class="identifier-syntax">x</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">best_nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. </b>It's a tricky task to choose from a list of possible nouns which might have
|
|
been intended by text such as "chair". If the list is empty or contains only
|
|
one choice, no problem. Otherwise we will probably have to reorder the noun
|
|
search list, and then run through it. The code below looks as if it picks out
|
|
the match with highest score, so that the ordering is unimportant, but in fact
|
|
the score assigned to a match is based purely on the number of words missed
|
|
out (see later): that means that ambiguities often arise between two lexically
|
|
similar objects, e.g., a "blue chair" or a "red chair" when the text simply
|
|
specifies "chair". Since the code below accepts the first noun with the
|
|
highest score, the outcome is thus determined by which of the blue and red
|
|
chairs ranks highest in the search list: and that is why the search list is so
|
|
important.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NOUN_DISAMBIGUATION_LINGUISTICS_CALLBACK</span><span class="plain-syntax"> </span><a href="4-nr.html#SP12" class="function-link"><span class="function-syntax">NameResolution::choose_highest_scoring_noun</span></a>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">noun_usage</span><span class="plain-syntax"> *</span><span class="function-syntax">NameResolution::choose_highest_scoring_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">common_only</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP9" class="function-link"><span class="function-syntax">NameResolution::construct_noun_search_list</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">noun</span><span class="plain-syntax">) </span><a href="4-nr.html#SP11" class="function-link"><span class="function-syntax">NameResolution::set_noun_search_score</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun_usage</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nu</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Nouns::usage_from_excerpt_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Nouns::is_eligible_match</span><span class="plain-syntax">(</span><span class="identifier-syntax">nu</span><span class="plain-syntax">-></span><span class="identifier-syntax">noun_used</span><span class="plain-syntax">, </span><span class="identifier-syntax">common_only</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="4-nr.html#SP11" class="function-link"><span class="function-syntax">NameResolution::set_noun_search_score</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nu</span><span class="plain-syntax">-></span><span class="identifier-syntax">noun_used</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_score</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-nr.html#SP11" class="function-link"><span class="function-syntax">NameResolution::highest_scoring_noun_searched</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">noun_usage</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nu</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Nouns::usage_from_excerpt_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nu</span><span class="plain-syntax">-></span><span class="identifier-syntax">noun_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">nt</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nu</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> should never in fact happen</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="3-nar2.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-bv.html">2</a></li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresscurrent">nr</li><li class="progresssection"><a href="4-rpt.html">rpt</a></li><li class="progresssection"><a href="4-tc.html">tc</a></li><li class="progresssection"><a href="4-ass.html">ass</a></li><li class="progresssection"><a href="4-npa.html">npa</a></li><li class="progresssection"><a href="4-pk.html">pk</a></li><li class="progresssection"><a href="4-rk.html">rk</a></li><li class="progresssection"><a href="4-ass2.html">ass2</a></li><li class="progresssection"><a href="4-imp.html">imp</a></li><li class="progresssection"><a href="4-tc2.html">tc2</a></li><li class="progresschapter"><a href="5-kpr.html">5</a></li><li class="progresschapter"><a href="6-tc.html">6</a></li><li class="progressnext"><a href="4-rpt.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|