1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/knowledge-module/4-is.html
2021-02-06 18:00:34 +00:00

754 lines
142 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Inference Subjects</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="../assertions-module/index.html">assertions</a></li>
<li><a href="../values-module/index.html">values</a></li>
<li><a href="index.html"><span class="selectedlink">knowledge</span></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 'Inference Subjects' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7</a></li><li><a href="index.html">knowledge</a></li><li><a href="index.html#4">Chapter 4: Inference and Model</a></li><li><b>Inference Subjects</b></li></ul></div>
<p class="purpose">The different data structures for elements of the model world are all unified by a single concept, the inference subject, about which facts can be known.</p>
<ul class="toc"><li><a href="4-is.html#SP7">&#167;7. The fundamentals</a></li><li><a href="4-is.html#SP8">&#167;8. Creation</a></li><li><a href="4-is.html#SP11">&#167;11. Aliasing</a></li><li><a href="4-is.html#SP12">&#167;12. Breadth</a></li><li><a href="4-is.html#SP17">&#167;17. Back conversions</a></li><li><a href="4-is.html#SP21">&#167;21. Logging</a></li><li><a href="4-is.html#SP23">&#167;23. Methods</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>"Creating a program often means that you have to create a small
universe" (Donald Knuth).
</p>
<p class="commentary">Inform's model world is the collection of objects and values which
contingently rather than necessarily exist, together with their properties
and relations. A number such as 267 exists of necessity &mdash; there would be
such a number whatever the source text had said, even if (as it turned out)
the compiled code never actually used it. But a room such as "The Great
Hall of Memphis", or a named value such as "aquamarine", need not exist.
Those are the stuff of the model.
</p>
<p class="commentary">As we have seen, the A-parser reduces assertion sentences in the source text
into logical propositions; these are then asserted in turn, reducing them
to a series of creations (such as that a ball exists) and a series of
inferences (such as that the ball is red). Inferences are elementary facts
about properties and relations, believed with different levels of certainty.
</p>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>An "inference subject" is anything about which an inference can be drawn.
These subjects form a hierarchy. We say that I inherits from J if a fact about I
is necessarily also a fact about J, unless directly contradicted by specific
information about J. For example,
</p>
<blockquote>
<p>The plastic bag is a container. A container is usually opaque. The bag is transparent.</p>
</blockquote>
<p class="commentary">The inference subject for the bag inherits from that for the container, so
without that final sentence, the bag would have been opaque.
</p>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>This is in effect a class with subclasses, but since we are using plain C
we indicate that with an enumeration of constants:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">FUND_SUB</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> one of a few fixed and fundamental subjects (see below)</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">KIND_SUB</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> a kind (number, thing, etc.)</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INST_SUB</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> an instance (specific objects, scenes, etc.)</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VARI_SUB</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax"> </span><span class="comment-syntax"> a non-local variable</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">RELN_SUB</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax"> </span><span class="comment-syntax"> a binary predicate, i.e., a relation</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_SUB</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax"> </span><span class="comment-syntax"> must be the largest of the values above</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Technically the hierarchy of inference subjects is a spaghetti stack, not a
tree: that is, all of the links run upwards to a common root (<span class="extract"><span class="extract-syntax">model_world</span></span>).
There is no direct way to access the links downwards from any node &mdash; in other
words, we often want to know what a given subject S inherits from, but we never
ask what other subjects inherit from S.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">TERM_DOMAIN_CALCULUS_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">TERM_DOMAIN_WORDING_FUNCTION</span><span class="plain-syntax"> </span><a href="4-is.html#SP23" class="function-link"><span class="function-syntax">InferenceSubjects::get_name_text</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">TERM_DOMAIN_TO_KIND_FUNCTION</span><span class="plain-syntax"> </span><a href="4-is.html#SP20" class="function-link"><span class="function-syntax">InferenceSubjects::domain</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">TERM_DOMAIN_FROM_KIND_FUNCTION</span><span class="plain-syntax"> </span><a href="4-kak.html#SP1" class="function-link"><span class="function-syntax">Kinds::Knowledge::as_subject</span></a>
</pre>
<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">inference_subject</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">kind_of_infs</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_SUB</span></span><span class="comment-syntax"> constants above</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">represents</span><span class="plain-syntax">; </span><span class="comment-syntax"> the individual instance, kind, etc. in question</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_created_at</span><span class="plain-syntax">; </span><span class="comment-syntax"> which sentence created this</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> contingently true: inferences drawn about this subject</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">implication</span><span class="plain-syntax"> *</span><span class="identifier-syntax">imp_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> necessarily true: implications applying to this</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">default_certainty</span><span class="plain-syntax">; </span><span class="comment-syntax"> by default, how certain are inferences about this?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">property_permission</span><span class="plain-syntax"> *</span><span class="identifier-syntax">permissions_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> what properties this can have, if any</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">assemblies_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">assemblies</span><span class="plain-syntax">; </span><span class="comment-syntax"> what generalisations have been made about this?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">broader_than</span><span class="plain-syntax">; </span><span class="comment-syntax"> see below</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_name_in_log</span><span class="plain-syntax">; </span><span class="comment-syntax"> solely to make the debugging log more legible</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alias_variable</span><span class="plain-syntax">; </span><span class="comment-syntax"> alias to this variable, like "yourself" to "player"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">plugin_subj</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_PLUGINS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inference_subject is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Recall that plugins are pieces of Inform which provide specialist additions
to the core language; to do this, they often need to attach further data to
</p>
<ul class="items"><li>(core) Inform's existing data structures. Once again, inference subjects provide
a convenient umbrella for things we're interested in; so we handle this by
allowing plugins to attach (suitably allocated) data structures to the ominous
<span class="extract"><span class="extract-syntax">void *</span></span> slots in the structure above.
</li></ul>
<p class="commentary">It's convenient to hide all of this by accessing the extra fields with the
macros below. Thus <span class="extract"><span class="extract-syntax">PF_S(balloons, gas)</span></span> is the lvalue (and rvalue) for
the <span class="extract"><span class="extract-syntax">gas</span></span> field added to the inference structure by <span class="extract"><span class="extract-syntax">balloons_plugin</span></span>.
The variation <span class="extract"><span class="extract-syntax">PF_I</span></span> is a shorthand to access the structure corresponding
to a given instance &mdash; that's actually what we want, most of the time,
since a lot of the plugins are interested more in IF concepts like rooms,
containers and people than in anything else, and all of those objects
are instances.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">PF_S</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_data</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plugin_subj</span><span class="plain-syntax">[</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_plugin</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">])</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">PF_I</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_data</span><span class="plain-syntax"> *) (</span><a href="2-ins.html#SP12" class="function-link"><span class="function-syntax">Instances::as_subject</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">))-&gt;</span><span class="element-syntax">plugin_subj</span><span class="plain-syntax">[</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_plugin</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">])</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">CREATE_PF_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">creator</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">S</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">plugin_subj</span><span class="plain-syntax">[</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_plugin</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">] = (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) (</span><span class="identifier-syntax">creator</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">));</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>The top of the inference hierarchy contains a number of "fundamental" subjects.
Thus we have:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> model_world</span>
<span class="plain-syntax"> nonlocal_variables</span>
<span class="plain-syntax"> ...all individual globals</span>
<span class="plain-syntax"> global_constants</span>
<span class="plain-syntax"> ...all kinds, including:</span>
<span class="plain-syntax"> K_object</span>
<span class="plain-syntax"> K_thing</span>
<span class="plain-syntax"> K_container</span>
<span class="plain-syntax"> ...</span>
<span class="plain-syntax"> K_room</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">(Note that objects appear within the hierarchy of values, rather than alongside
it, as in the class hierarchies of languages like Scala.)
</p>
<p class="commentary">For instance, by giving <span class="extract"><span class="extract-syntax">nonlocal_variables</span></span> permission to have the "initial
value" property, we immediately grant the same to every global variable, by
inheritance.
</p>
<p class="commentary">Inheritance forms a directed acyclic graph with <span class="extract"><span class="extract-syntax">model_world</span></span> as the root.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">model_world</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nonlocal_variables</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">global_constants</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">relations</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>&#167;7. The fundamentals. </b>At the start of Inform's run, the subject tree consists only of the
following.
</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">InferenceSubjects::make_built_in</span><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">model_world</span><span class="plain-syntax"> = </span><a href="4-is.html#SP7" class="function-link"><span class="function-syntax">InferenceSubjects::new_fundamental</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="string-syntax">"model-world"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nonlocal_variables</span><span class="plain-syntax"> = </span><a href="4-is.html#SP7" class="function-link"><span class="function-syntax">InferenceSubjects::new_fundamental</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">model_world</span><span class="plain-syntax">, </span><span class="string-syntax">"global-variables"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">global_constants</span><span class="plain-syntax"> = </span><a href="4-is.html#SP7" class="function-link"><span class="function-syntax">InferenceSubjects::new_fundamental</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">model_world</span><span class="plain-syntax">, </span><span class="string-syntax">"global-constants"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">relations</span><span class="plain-syntax"> = </span><a href="4-is.html#SP7" class="function-link"><span class="function-syntax">InferenceSubjects::new_fundamental</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">model_world</span><span class="plain-syntax">, </span><span class="string-syntax">"relations"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Plugins::Call::create_inference_subjects</span><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::new_fundamental</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lname</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP9" class="function-link"><span class="function-syntax">InferenceSubjects::infs_initialise</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL_GENERAL_POINTER</span><span class="plain-syntax">, </span><span class="constant-syntax">FUND_SUB</span><span class="plain-syntax">, </span><span class="identifier-syntax">LIKELY_CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">lname</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">infs</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Creation. </b>Other inference subjects are added during the run, thus:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::new</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">InferenceSubjects::new</span></span>:<br/>Instances - <a href="2-ins.html#SP5_2">&#167;5.2</a><br/>Nonlocal Variables - <a href="2-nv.html#SP6_3">&#167;6.3</a><br/>Knowledge about Kinds - <a href="4-kak.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">KOI</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">gp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cert</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP9" class="function-link"><span class="function-syntax">InferenceSubjects::infs_initialise</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">gp</span><span class="plain-syntax">, </span><span class="identifier-syntax">KOI</span><span class="plain-syntax">, </span><span class="identifier-syntax">cert</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>Either means of creation uses the following:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_roots</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">InferenceSubjects::infs_initialise</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">InferenceSubjects::infs_initialise</span></span>:<br/><a href="4-is.html#SP7">&#167;7</a>, <a href="4-is.html#SP8">&#167;8</a>, <a href="4-is.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">gp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">KOI</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cert</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lname</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">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (++</span><span class="identifier-syntax">no_roots</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP22" class="function-link"><span class="function-syntax">InferenceSubjects::log_infs_hierarchy</span></a><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">"subject tree now disconnected"</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">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">infs</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"made sub-subject of itself"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">infs_created_at</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">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">represents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">gp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">kind_of_infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KOI</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">inf_list</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">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">imp_list</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">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">broader_than</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_certainty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cert</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">permissions_list</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">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">infs_name_in_log</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lname</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">alias_variable</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">Assertions::Assemblies::initialise_assemblies_data</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">assemblies</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">i</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">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">MAX_PLUGINS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plugin_subj</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</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">Plugins::Call::new_subject_notify</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Renewal is needed to solve a timing problem early in Inform's run, since
subjects for spatial kinds like "room" are needed before the kinds themselves
can be made. Abusing this routine could clearly violate the rule that the
subject tree must remain a connected DAG, so we don't abuse it.
</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">InferenceSubjects::renew</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">KOI</span><span class="plain-syntax">, </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">gp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cert</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP9" class="function-link"><span class="function-syntax">InferenceSubjects::infs_initialise</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">gp</span><span class="plain-syntax">, </span><span class="identifier-syntax">KOI</span><span class="plain-syntax">, </span><span class="identifier-syntax">cert</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</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="SP11" class="paragraph-anchor"></a><b>&#167;11. Aliasing. </b>This is explained in the "The Player" plugin, which is the only place where
it's needed at present.
</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">InferenceSubjects::alias_to_nonlocal_variable</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">q</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">alias_variable</span><span class="plain-syntax"> = </span><span class="identifier-syntax">q</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::aliased_but_diverted</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">InferenceSubjects::aliased_but_diverted</span></span>:<br/>Instance Counting - <a href="4-ic.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alias_variable</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vs</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="2-ins.html#SP12" class="function-link"><span class="function-syntax">Instances::as_subject</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::to_object_instance</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="2-nv.html#SP16" class="function-link"><span class="function-syntax">NonlocalVariables::get_initial_value</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alias_variable</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">vs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">vs</span><span class="plain-syntax"> != </span><span class="identifier-syntax">infs</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Breadth. </b>Some subjects are broad, covering many things, and others narrow &mdash; perhaps
used to specify facts about only a single person or value.
</p>
<p class="commentary">Either two different subjects are disjoint or one strictly contains the other.
This makes testing for containment simple:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::is_within</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">InferenceSubjects::is_within</span></span>:<br/><a href="4-is.html#SP14">&#167;14</a><br/>Indefinite Appearance - <a href="3-ia.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">smaller</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">larger</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">smaller</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">smaller</span><span class="plain-syntax"> == </span><span class="identifier-syntax">larger</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">smaller</span><span class="plain-syntax"> = </span><span class="identifier-syntax">smaller</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">broader_than</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">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::is_strictly_within</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">larger</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">subj</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="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-is.html#SP12" class="function-link"><span class="function-syntax">InferenceSubjects::is_within</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">broader_than</span><span class="plain-syntax">, </span><span class="identifier-syntax">larger</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>Where possible, we use the above tests; where we need to perform other
operations scaling the subject tree, we use the following:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::narrowest_broader_subject</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">InferenceSubjects::narrowest_broader_subject</span></span>:<br/>Instances - <a href="2-ins.html#SP17">&#167;17</a><br/>Properties - <a href="3-prp.html#SP24">&#167;24</a><br/>Properties of Values - <a href="3-pov.html#SP4">&#167;4</a><br/>Emit Property Values - <a href="3-epv.html#SP1">&#167;1</a>, <a href="3-epv.html#SP1_1_4">&#167;1.1.4</a><br/>Knowledge about Kinds - <a href="4-kak.html#SP6">&#167;6</a>, <a href="4-kak.html#SP7">&#167;7</a><br/>Property Permissions - <a href="4-pp.html#SP7">&#167;7</a><br/>Inferences - <a href="4-inf.html#SP13">&#167;13</a>, <a href="4-inf.html#SP15">&#167;15</a><br/>Complete Model World - <a href="4-cmw.html#SP1_2_2_1">&#167;1.2.2.1</a><br/>Instance Counting - <a href="4-ic.html#SP11_3">&#167;11.3</a>, <a href="4-ic.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">narrow</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">narrow</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="identifier-syntax">NULL</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">narrow</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">broader_than</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>The containment hierarchy is a fluid one, but subjects may only be demoted.
This means that any information derived from a subject's position relative to
other subjects, before the change, continues to be valid. If \(S\subseteq T\)
before, then this remains true afterwards.
</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">InferenceSubjects::falls_within</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">InferenceSubjects::falls_within</span></span>:<br/>Instances - <a href="2-ins.html#SP18">&#167;18</a><br/>Knowledge about Kinds - <a href="4-kak.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">narrow</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">broad</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-is.html#SP12" class="function-link"><span class="function-syntax">InferenceSubjects::is_within</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">broad</span><span class="plain-syntax">, </span><span class="identifier-syntax">narrow</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">broader_than</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"subject breadth change leads to inconsistency"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">narrow</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">broader_than</span><span class="plain-syntax"> = </span><span class="identifier-syntax">broad</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>Now access to the knowledge we possess about subjects, all of which is
read and written from specialist sections of Inform rather than here.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::where_created</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</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">"null INFS"</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">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_created_at</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::get_default_certainty</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">InferenceSubjects::get_default_certainty</span></span>:<br/>Inferences - <a href="4-inf.html#SP7">&#167;7</a>, <a href="4-inf.html#SP19_3">&#167;19.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_certainty</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">assemblies_data</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</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 assembly data for null subject"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> &amp;(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">assemblies</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::get_inferences</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">InferenceSubjects::get_inferences</span></span>:<br/><a href="4-is.html#SP21">&#167;21</a><br/>Inferences - <a href="4-inf.html#SP12">&#167;12</a>, <a href="4-inf.html#SP19">&#167;19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inf_list</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::set_inferences</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">InferenceSubjects::set_inferences</span></span>:<br/>Inferences - <a href="4-inf.html#SP19_1">&#167;19.1</a>, <a href="4-inf.html#SP19_3_1">&#167;19.3.1</a>, <a href="4-inf.html#SP19_3_4">&#167;19.3.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</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">infs</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">"null INFS"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">inf_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">implication</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::get_implications</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">imp_list</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">InferenceSubjects::set_implications</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">implication</span><span class="plain-syntax"> *</span><span class="identifier-syntax">imp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">imp_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">property_permission</span><span class="plain-syntax"> **</span><span class="function-syntax">InferenceSubjects::get_permissions</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::get_permissions</span></span>:<br/>Property Permissions - <a href="4-pp.html#SP6">&#167;6</a>, <a href="4-pp.html#SP8_2">&#167;8.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> &amp;(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">permissions_list</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>Forward conversions.
Suppose we have a constant value, or more generally, a specification. Does this
correspond to a subject, and if so, which one?
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::from_specification</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::from_specification</span></span>:<br/>Assert Propositions - <a href="1-ap.html#SP11">&#167;11</a><br/>Nonlocal Variables - <a href="2-nv.html#SP23">&#167;23</a><br/>Knowledge about Relations - <a href="4-kar.html#SP2">&#167;2</a><br/>Inferences - <a href="4-inf.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">Specifications::is_kind_like</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><a href="4-kak.html#SP1" class="function-link"><span class="function-syntax">Kinds::Knowledge::as_subject</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</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">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::to_object_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">I</span><span class="plain-syntax">) </span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><a href="2-ins.html#SP12" class="function-link"><span class="function-syntax">Instances::as_subject</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</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">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::to_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">nc</span><span class="plain-syntax">) </span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><a href="2-ins.html#SP12" class="function-link"><span class="function-syntax">Instances::as_subject</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nc</span><span class="plain-syntax">);</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">infs</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Back conversions. </b>In the end subjects are, in part, wrappers to unify a range of other data
structures, and sometimes we want to tear off the wrapper. The following is
almost the inverse of the function above &mdash; for inference subjects or for
specifications they correspond to, they are indeed inverses; for other
specifications, forward conversion returns <span class="extract"><span class="extract-syntax">NULL</span></span> and the question doesn't
arise.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_constant</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_constant</span></span>:<br/>Assert Propositions - <a href="1-ap.html#SP8_7">&#167;8.7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="4-is.html#SP20" class="function-link"><span class="function-syntax">InferenceSubjects::domain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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">K</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Specifications::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><a href="4-is.html#SP18" class="function-link"><span class="function-syntax">InferenceSubjects::as_object_instance</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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">I</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::from_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nc</span><span class="plain-syntax"> = </span><a href="4-is.html#SP18" class="function-link"><span class="function-syntax">InferenceSubjects::as_nc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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">nc</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::from_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">nc</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="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>More prosaically:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_instance</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_instance</span></span>:<br/>Instances - <a href="2-ins.html#SP27">&#167;27</a><br/>Emit Property Values - <a href="3-epv.html#SP1">&#167;1</a>, <a href="3-epv.html#SP2">&#167;2</a>, <a href="3-epv.html#SP2_1">&#167;2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">INST_SUB</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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">nc</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="plain-syntax">}</span>
<span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_object_instance</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_object_instance</span></span>:<br/><a href="4-is.html#SP17">&#167;17</a>, <a href="4-is.html#SP19">&#167;19</a><br/>Assert Propositions - <a href="1-ap.html#SP9">&#167;9</a><br/>Inferences - <a href="4-inf.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">INST_SUB</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><a href="2-ins.html#SP17" class="function-link"><span class="function-syntax">Instances::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nc</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">nc</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="plain-syntax">}</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_nonobject_kind</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_nonobject_kind</span></span>:<br/><a href="4-is.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">KIND_SUB</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::base_construction</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RETRIEVE_POINTER_kind_constructor</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</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="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K</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="plain-syntax">}</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_kind</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_kind</span></span>:<br/><a href="4-is.html#SP20">&#167;20</a><br/>Instances - <a href="2-ins.html#SP17">&#167;17</a><br/>Properties - <a href="3-prp.html#SP26">&#167;26</a><br/>Emit Property Values - <a href="3-epv.html#SP1">&#167;1</a>, <a href="3-epv.html#SP2">&#167;2</a>, <a href="3-epv.html#SP2_1">&#167;2.1</a><br/>Knowledge about Kinds - <a href="4-kak.html#SP3">&#167;3</a>, <a href="4-kak.html#SP5">&#167;5</a>, <a href="4-kak.html#SP6">&#167;6</a>, <a href="4-kak.html#SP7">&#167;7</a><br/>Instance Counting - <a href="4-ic.html#SP11_3">&#167;11.3</a>, <a href="4-ic.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">KIND_SUB</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::base_construction</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RETRIEVE_POINTER_kind_constructor</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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">K</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="plain-syntax">}</span>
<span class="reserved-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_nlv</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_nlv</span></span>:<br/>Nonlocal Variables - <a href="2-nv.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">VARI_SUB</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">RETRIEVE_POINTER_nonlocal_variable</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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="plain-syntax">}</span>
<span class="identifier-syntax">binary_predicate</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_bp</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_bp</span></span>:<br/><a href="4-is.html#SP21">&#167;21</a><br/>Knowledge about Relations - <a href="4-kar.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">RELN_SUB</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">RETRIEVE_POINTER_binary_predicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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="plain-syntax">}</span>
<span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::as_nc</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::as_nc</span></span>:<br/><a href="4-is.html#SP17">&#167;17</a><br/>Instances - <a href="2-ins.html#SP26">&#167;26</a>, <a href="2-ins.html#SP28">&#167;28</a>, <a href="2-ins.html#SP33">&#167;33</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">INST_SUB</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">RETRIEVE_POINTER_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>...and, because it makes conditions more legible,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::is_an_object</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::is_an_object</span></span>:<br/>Emit Property Values - <a href="3-epv.html#SP3_1">&#167;3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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-is.html#SP18" class="function-link"><span class="function-syntax">InferenceSubjects::as_object_instance</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</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">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::is_a_kind_of_object</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::is_a_kind_of_object</span></span>:<br/>Emit Property Values - <a href="3-epv.html#SP3_1">&#167;3.1</a><br/>Knowledge about Kinds - <a href="4-kak.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="constant-syntax">KIND_SUB</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::base_construction</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RETRIEVE_POINTER_kind_constructor</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">represents</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">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>Finally, just as subjects can represent individual values, so they can
also represent collections of values. (At present, though, only the subjects
from kinds actually do.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::domain</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::domain</span></span>:<br/><a href="4-is.html#SP4">&#167;4</a>, <a href="4-is.html#SP17">&#167;17</a><br/>Either-Or Properties - <a href="3-ep.html#SP3">&#167;3</a><br/>Indefinite Appearance - <a href="3-ia.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-is.html#SP18" class="function-link"><span class="function-syntax">InferenceSubjects::as_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Logging. </b></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">InferenceSubjects::log</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::log</span></span>:<br/>Knowledge Module - <a href="1-km.html#SP2">&#167;2</a>, <a href="1-km.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;null infs&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</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">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_name_in_log</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"infs&lt;%s&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_name_in_log</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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="4-is.html#SP23" class="function-link"><span class="function-syntax">InferenceSubjects::get_name_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="4-is.html#SP18" class="function-link"><span class="function-syntax">InferenceSubjects::as_nonobject_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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">K</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"infs'%u'-k"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</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">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"infs'%W'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</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">binary_predicate</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax"> = </span><a href="4-is.html#SP18" class="function-link"><span class="function-syntax">InferenceSubjects::as_bp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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">bp</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"infs'%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">BinaryPredicates::get_log_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">bp</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">"infs%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</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">InferenceSubjects::log_knowledge_about</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</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">"Inferences drawn about $j:\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG_INDENT</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">inf</span><span class="plain-syntax"> = </span><a href="4-is.html#SP15" class="function-link"><span class="function-syntax">InferenceSubjects::get_inferences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="identifier-syntax">inf</span><span class="plain-syntax">; </span><span class="identifier-syntax">inf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$I\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>The subjects hierarchy is unlikely to reach a depth of 20 except by a bug,
but that's exactly when we need the debugging log most, so the following is
coded to ensure that it terminates whether or not the subjects form a connected
DAG.
</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">InferenceSubjects::log_infs_hierarchy</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::log_infs_hierarchy</span></span>:<br/><a href="4-is.html#SP9">&#167;9</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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Subjects hierarchy:\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP22" class="function-link"><span class="function-syntax">InferenceSubjects::log_subjects_hierarchically</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::log_subjects_hierarchically</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</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">count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">20</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"*** Pruning: too deep ***\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</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">infs</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$j\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">narrower</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">narrower</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</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">narrower</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">broader_than</span><span class="plain-syntax"> == </span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP22" class="function-link"><span class="function-syntax">InferenceSubjects::log_subjects_hierarchically</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">narrower</span><span class="plain-syntax">, </span><span class="identifier-syntax">count</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. Methods. </b>The first of these should fill in a name, if one is available, placing the
word range into the variables pointed to by <span class="extract"><span class="extract-syntax">w1</span></span> and <span class="extract"><span class="extract-syntax">w2</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::get_name_text</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::get_name_text</span></span>:<br/><a href="4-is.html#SP4">&#167;4</a>, <a href="4-is.html#SP21">&#167;21</a><br/>Condition Properties - <a href="3-cp.html#SP3_1">&#167;3.1</a><br/>Property Permissions - <a href="4-pp.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</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">"null INFS"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="4-kak.html#SP3" class="function-link"><span class="function-syntax">Kinds::Knowledge::get_name_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="2-ins.html#SP26" class="function-link"><span class="function-syntax">Instances::SUBJ_get_name_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_get_name_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_get_name_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</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">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">STROKE_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::up_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</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">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b>In general property permissions work just as well whatever subject is getting
the new property, but the following is called to give the subject a chance to
react. It should return a general pointer to any extra data it wants to attach
to the permission, or <span class="extract"><span class="extract-syntax">NULL_GENERAL_POINTER</span></span> if it has nothing to add.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::new_permission_granted</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::new_permission_granted</span></span>:<br/>Property Permissions - <a href="4-pp.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</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">"null INFS"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-kak.html#SP4" class="function-link"><span class="function-syntax">Kinds::Knowledge::new_permission_granted</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-ins.html#SP26" class="function-link"><span class="function-syntax">Instances::SUBJ_new_permission_granted</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_new_permission_granted</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_new_permission_granted</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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_GENERAL_POINTER</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>Suppose there is an instance, such as "green", belonging to a kind of
value which coincides with a property of some subject. Then the following is
called to tell the subject in question that it needs to become the domain
of "green" as an adjective.
</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">InferenceSubjects::make_adj_const_domain</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::make_adj_const_domain</span></span>:<br/>Instances - <a href="2-ins.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nc</span><span class="plain-syntax">, </span><span class="reserved-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</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">infs</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">"null INFS"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><a href="4-kak.html#SP5" class="function-link"><span class="function-syntax">Kinds::Knowledge::make_adj_const_domain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">nc</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><a href="2-ins.html#SP27" class="function-link"><span class="function-syntax">Instances::SUBJ_make_adj_const_domain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">nc</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_make_adj_const_domain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">nc</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_make_adj_const_domain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">nc</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. </b>Part of the process of "completing" the model &mdash; that is, filling in detail
not spelled out explicitly in assertion sentences &mdash; is to ask each subject
to fill in anything missing about itself:
</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">InferenceSubjects::complete_model</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::complete_model</span></span>:<br/>Complete Model World - <a href="4-cmw.html#SP1_1">&#167;1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</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">"null INFS"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><a href="4-kak.html#SP3" class="function-link"><span class="function-syntax">Kinds::Knowledge::complete_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><a href="2-ins.html#SP26" class="function-link"><span class="function-syntax">Instances::SUBJ_complete_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_complete_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_complete_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. </b>Each subject also has a chance to check the knowledge about it for
consistency, and to issue problem messages if something is wrong:
</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">InferenceSubjects::check_model</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::check_model</span></span>:<br/>Complete Model World - <a href="4-cmw.html#SP1_2">&#167;1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</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">"null INFS"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><a href="4-kak.html#SP3" class="function-link"><span class="function-syntax">Kinds::Knowledge::check_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><a href="2-ins.html#SP26" class="function-link"><span class="function-syntax">Instances::SUBJ_check_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_check_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_check_model</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. </b>Here we must compile run-time code which tests whether the value in <span class="extract"><span class="extract-syntax">t_0</span></span>
is a constant which the subject gives information about, given that we already
know it has the right atomic kind. (In some cases there will be nothing to
test &mdash; if we know that <span class="extract"><span class="extract-syntax">t_0</span></span> has kind "number" then it must be what we want.
But in the case of objects, we need to check <span class="extract"><span class="extract-syntax">t_0</span></span> is not <span class="extract"><span class="extract-syntax">nothing</span></span> and that
it has the right kind, and so on. If there's nothing to check, we leave the
condition blank.)
</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">InferenceSubjects::emit_element_of_condition</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t0_s</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">infs</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">"null INFS"</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">written</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">written</span><span class="plain-syntax"> = </span><a href="4-kak.html#SP3" class="function-link"><span class="function-syntax">Kinds::Knowledge::emit_element_of_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">t0_s</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">written</span><span class="plain-syntax"> = </span><a href="2-ins.html#SP28" class="function-link"><span class="function-syntax">Instances::SUBJ_emit_element_of_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">t0_s</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">written</span><span class="plain-syntax"> = </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_emit_element_of_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">t0_s</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">written</span><span class="plain-syntax"> = </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_emit_element_of_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">t0_s</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</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">written</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">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>&#167;29. </b>The model world needs to have its complex initial state stored somewhere
at run-time. Each subject may need its own data structure, and we want no
part of thinking about what it looks like.
</p>
<p class="commentary">Each kind of subject has a chance to compile all its subjects at once,
which enables this to be done in a funny order or in some consolidated
array, or else have its subjects compiled one at a time in order of their
creation. <span class="extract"><span class="extract-syntax">compile_all</span></span> should return <span class="extract"><span class="extract-syntax">TRUE</span></span> to indicate the former course.
</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">InferenceSubjects::compile_all</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::compile_all</span></span>:<br/>Compile Model World - <a href="4-cmw2.html#SP2">&#167;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">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-inf.html#SP13" class="function-link"><span class="function-syntax">World::Inferences::verify_prop_states</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</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">koi</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">koi</span><span class="plain-syntax">=1; </span><span class="identifier-syntax">koi</span><span class="plain-syntax">&lt;=</span><span class="constant-syntax">MAX_SUB</span><span class="plain-syntax">; </span><span class="identifier-syntax">koi</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">done</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">koi</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">done</span><span class="plain-syntax"> = </span><a href="4-kak.html#SP6" class="function-link"><span class="function-syntax">Kinds::Knowledge::emit_all</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">done</span><span class="plain-syntax"> = </span><a href="2-ins.html#SP32" class="function-link"><span class="function-syntax">Instances::SUBJ_compile_all</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">done</span><span class="plain-syntax"> = </span><a href="2-nv.html#SP15" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_compile_all</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><span class="identifier-syntax">done</span><span class="plain-syntax"> = </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_compile_all</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</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">done</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</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">infs</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</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">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax"> == </span><span class="identifier-syntax">koi</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUND_SUB:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIND_SUB:</span><span class="plain-syntax"> </span><a href="4-kak.html#SP6" class="function-link"><span class="function-syntax">Kinds::Knowledge::emit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INST_SUB:</span><span class="plain-syntax"> </span><a href="2-ins.html#SP33" class="function-link"><span class="function-syntax">Instances::SUBJ_compile</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARI_SUB:</span><span class="plain-syntax"> </span><a href="2-nv.html#SP14" class="function-link"><span class="function-syntax">NonlocalVariables::SUBJ_compile</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">RELN_SUB:</span><span class="plain-syntax"> </span><a href="4-kar.html#SP1" class="function-link"><span class="function-syntax">KnowledgeAboutRelations::SUBJ_compile</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-epv.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-km.html">1</a></li><li class="progresschapter"><a href="2-ins.html">2</a></li><li class="progresschapter"><a href="3-prp.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresscurrent">is</li><li class="progresssection"><a href="4-kak.html">kak</a></li><li class="progresssection"><a href="4-kar.html">kar</a></li><li class="progresssection"><a href="4-pp.html">pp</a></li><li class="progresssection"><a href="4-inf.html">inf</a></li><li class="progresssection"><a href="4-cmw.html">cmw</a></li><li class="progresssection"><a href="4-cmw2.html">cmw2</a></li><li class="progresssection"><a href="4-ic.html">ic</a></li><li class="progresschapter"><a href="5-tc.html">5</a></li><li class="progresschapter"><a href="6-eqt.html">6</a></li><li class="progresschapter"><a href="7-rls.html">7</a></li><li class="progressnext"><a href="4-kak.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>