1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-05-19 09:28:51 +03:00
inform7/docs/knowledge-module/4-is.html
2023-09-10 23:46:39 +01:00

657 lines
110 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 src="http://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.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="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</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="../inform7n.html">Inform7</a></li><li><a href="index.html">knowledge</a></li><li><a href="index.html#4">Chapter 4: Subjects</a></li><li><b>Inference Subjects</b></li></ul></div>
<p class="purpose">A unified way to refer to the things propositions talk about.</p>
<ul class="toc"><li><a href="4-is.html#SP1">&#167;1. Families</a></li><li><a href="4-is.html#SP3">&#167;3. Hierarchy</a></li><li><a href="4-is.html#SP6">&#167;6. Creation of subjects</a></li><li><a href="4-is.html#SP8">&#167;8. Aliasing</a></li><li><a href="4-is.html#SP10">&#167;10. Breadth</a></li><li><a href="4-is.html#SP13">&#167;13. Access functions</a></li><li><a href="4-is.html#SP14">&#167;14. Conversions to and from kinds and instances</a></li><li><a href="4-is.html#SP17">&#167;17. Logging</a></li><li><a href="4-is.html#SP19">&#167;19. Methods</a></li><li><a href="4-is.html#SP28">&#167;28. Feature data</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Families. </b><a href="4-is.html#SP6" class="internal">inference_subject</a> is a type which can represent anything in the model
which a proposition can discuss: in particular, kinds, relations, variables
and instances. These have very different implementations, and so subjects
are divided into "families", and general functions on subjects are done
as method calls. There are (currently) five families.
</p>
<p class="commentary">Each family is an instance of:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">method_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">methods</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_family</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::new_family</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_family</span></span>:<br/><a href="4-is.html#SP2">&#167;2</a><br/>Variable Subjects - <a href="4-vs.html#SP1">&#167;1</a><br/>Instance Subjects - <a href="4-is2.html#SP1">&#167;1</a><br/>Kind Subjects - <a href="4-ks.html#SP1">&#167;1</a><br/>Relation Subjects - <a href="4-rs.html#SP1">&#167;1</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_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">methods</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Methods::new_set</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">f</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure inference_subject_family is accessed in 5/inf and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The "fundamentals" family will be defined here. As we will see, it is used
only for a few broad concepts. It provides few method functions, because these
subjects serve a mainly organisational role.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Though, for instance, by giving <span class="extract"><span class="extract-syntax">global_variables</span></span> permission to have the
"initial value" property, we immediately grant the same to every global
variable, by inheritance. So fundamental subjects have their uses.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fundamentals_family</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::fundamentals</span><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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fundamentals_family</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">fundamentals_family</span><span class="plain-syntax"> = </span><a href="4-is.html#SP1" class="function-link"><span class="function-syntax">InferenceSubjects::new_family</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">METHOD_ADD</span><span class="plain-syntax">(</span><span class="identifier-syntax">fundamentals_family</span><span class="plain-syntax">, </span><span class="constant-syntax">GET_DEFAULT_CERTAINTY_INFS_MTID</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-is.html#SP2" class="function-link"><span class="function-syntax">InferenceSubjects::fundamental_certainty</span></a><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">fundamentals_family</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::fundamental_certainty</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIKELY_CE</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><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::new_fundamental</span></span>:<br/><a href="4-is.html#SP5">&#167;5</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="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">log_name</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#SP7" class="function-link"><span class="function-syntax">InferenceSubjects::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><a href="4-is.html#SP2" class="function-link"><span class="function-syntax">InferenceSubjects::fundamentals</span></a><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NULL_GENERAL_POINTER</span><span class="plain-syntax">, </span><span class="identifier-syntax">log_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Hierarchy. </b>An "inference subject" is anything about which an inference can be drawn.
These subjects form a hierarchy.<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> I "inherits from" J if a fact about J
is necessarily also a fact about I, unless directly contradicted by specific
information about I. 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">Each subject has a link to the narrowest subject which is broader than it is.
For the bag subject, that would be the container subject; for the container
subject, it would be the thing subject; and so on.<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup>
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:2"><p class="inwebfootnote"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> A directed acyclic graph of the sort sometimes called a spaghetti stack, in
which all of the links run upwards to a common root &mdash; the <span class="extract"><span class="extract-syntax">model_world</span></span> subject,
which represents the entire model.
<a href="#fnref:2" title="return to text"> &#x21A9;</a></p></li><li class="footnote" id="fn:3"><p class="inwebfootnote"><sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> The subject hierarchy thus contains the same tree structure of
<a href="../kinds-module/2-tlok.html" class="internal">The Lattice of Kinds (in kinds)</a>, which is not a coincidence &mdash; see
but of course it includes instances and much else as well.
<a href="#fnref:3" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The top of the inference hierarchy is essentially fixed, and contains a number
of "fundamental" subjects:
</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">global_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="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>And these are set up in a tiny hierarchy, with <span class="extract"><span class="extract-syntax">model_world</span></span> at the top, the
one and only subject with no broader subject:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> model_world</span>
<span class="plain-syntax"> global_variables</span>
<span class="plain-syntax"> global_constants</span>
<span class="plain-syntax"> relations</span>
</pre>
<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#SP2" 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">global_variables</span><span class="plain-syntax"> = </span><a href="4-is.html#SP2" 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#SP2" 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#SP2" 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">PluginCalls::create_inference_subjects</span><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Creation of subjects. </b>Each subject is an instance of:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> {</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"> going up in the hierarchy</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_family</span><span class="plain-syntax">;</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"> family-specific data</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">additional_data_for_features</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_COMPILER_FEATURES</span><span class="plain-syntax">]; </span><span class="comment-syntax"> and managed by those features</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> contingently true: each </span><span class="extract"><span class="extract-syntax">inference</span></span><span class="comment-syntax"> drawn about this</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">imp_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> necessarily true: each </span><span class="extract"><span class="extract-syntax">implication</span></span><span class="comment-syntax"> applying to this</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">permissions_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">property_permission</span></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">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alias_variable</span><span class="plain-syntax">; </span><span class="comment-syntax"> in the way that "player" aliases "yourself"</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">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="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 accessed in 4/vs, 4/is2, 4/ks, 4/rs and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>The following is provided as two functions, not one, so that a subject can
be reinitialised. (This is used to get around awkward timing problems with some
of the basic kinds in the <a href="../if-module/index.html" class="internal">if</a> module: a placeholder subject is made for
"thing" early in the run, and then is reinitialised as the subject for this
kind once the kind itself is created.)
</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('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::new</span></span>:<br/><a href="4-is.html#SP2">&#167;2</a><br/>Variable Subjects - <a href="4-vs.html#SP1">&#167;1</a><br/>Instance Subjects - <a href="4-is2.html#SP1">&#167;1</a><br/>Kind Subjects - <a href="4-ks.html#SP2">&#167;2</a><br/>Relation Subjects - <a href="4-rs.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="plain-syntax"> </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">family</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">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">log_name</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#SP7" 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">family</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">log_name</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>
<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('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::infs_initialise</span></span>:<br/>Kind Subjects - <a href="4-ks.html#SP4">&#167;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="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">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">family</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">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">log_name</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#SP18" 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="element-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="element-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="element-syntax">infs_family</span><span class="plain-syntax"> = </span><span class="identifier-syntax">family</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="element-syntax">inf_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference</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="element-syntax">imp_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">implication</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="element-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="element-syntax">permissions_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">property_permission</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="element-syntax">infs_name_in_log</span><span class="plain-syntax"> = </span><span class="identifier-syntax">log_name</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="element-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">for</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">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">MAX_COMPILER_FEATURES</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">additional_data_for_features</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">PluginCalls::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="SP8" class="paragraph-anchor"></a><b>&#167;8. Aliasing. </b>See <a href="../if-module/3-tp.html" class="internal">The Player (in if)</a>, which is the only place where this is needed at present.
It has to do with the difference between "yourself" and "the player".
</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="element-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><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">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#SP6" 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="4-vs.html#SP2" class="function-link"><span class="function-syntax">VariableSubjects::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="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>Diversion is a similar tactic used to re-route knowledge about the "yourself"
instance to become knowledge about the initial value of "player" instead:
</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::divert</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::divert</span></span>:<br/>Inferences - <a href="5-inf.html#SP5">&#167;5</a>, <a href="5-inf.html#SP8">&#167;8</a><br/>Relation Inferences - <a href="5-ri.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><a href="5-tmw.html#SP1" class="function-link"><span class="function-syntax">World::current_building_stage</span></a><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">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">alias_variable</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><a href="4-vs.html#SP2" class="function-link"><span class="function-syntax">VariableSubjects::get_initial_value</span></a><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">divert</span><span class="plain-syntax"> = </span><a href="4-is.html#SP14" class="function-link"><span class="function-syntax">InferenceSubjects::from_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</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">divert</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">divert</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="SP10" class="paragraph-anchor"></a><b>&#167;10. 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('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::is_within</span></span>:<br/><a href="4-is.html#SP12">&#167;12</a><br/>Indefinite Appearance - <a href="5-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#SP10" 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="SP11" class="paragraph-anchor"></a><b>&#167;11. </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('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::narrowest_broader_subject</span></span>:<br/>Instances - <a href="2-ins.html#SP10">&#167;10</a><br/>Properties - <a href="3-prp.html#SP17">&#167;17</a><br/>Kind Subjects - <a href="4-ks.html#SP10">&#167;10</a><br/>Property Permissions - <a href="4-pp.html#SP2">&#167;2</a><br/>Property Inferences - <a href="5-pi.html#SP9">&#167;9</a>, <a href="5-pi.html#SP14">&#167;14</a><br/>The Model World - <a href="5-tmw.html#SP4_2_1">&#167;4.2.1</a><br/>The Naming Thicket - <a href="5-tnt.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">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="SP12" class="paragraph-anchor"></a><b>&#167;12. </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('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::falls_within</span></span>:<br/>Instances - <a href="2-ins.html#SP11">&#167;11</a><br/>Kind Subjects - <a href="4-ks.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">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#SP10" 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="SP13" class="paragraph-anchor"></a><b>&#167;13. Access functions. </b></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="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="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="function-syntax">InferenceSubjects::get_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::get_inferences</span></span>:<br/><a href="4-is.html#SP17">&#167;17</a><br/>Inferences - <a href="5-inf.html#SP5">&#167;5</a>, <a href="5-inf.html#SP8">&#167;8</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="identifier-syntax">linked_list</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="identifier-syntax">linked_list</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#SP2">&#167;2</a>, <a href="4-pp.html#SP3_2">&#167;3.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"> </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="SP14" class="paragraph-anchor"></a><b>&#167;14. Conversions to and from kinds and instances. </b>Note that the following does not pick up variables (in the form of their lvalue
specifications) or relations (from their rvalue constants): it handles only
kinds and instances.
</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/><a href="4-is.html#SP9">&#167;9</a><br/>Assert Propositions - <a href="1-ap.html#SP9">&#167;9</a><br/>Nonlocal Variables - <a href="2-nv.html#SP14">&#167;14</a><br/>Relation Subjects - <a href="4-rs.html#SP4">&#167;4</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-ks.html#SP3" class="function-link"><span class="function-syntax">KindSubjects::from_kind</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">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#SP6" 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="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="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>And this amounts to a partial inverse of that function:
</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#SP6_7">&#167;6.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-ks.html#SP3" class="function-link"><span class="function-syntax">KindSubjects::to_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="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">nc</span><span class="plain-syntax"> = </span><a href="4-is2.html#SP1" class="function-link"><span class="function-syntax">InstanceSubjects::to_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">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="SP16" class="paragraph-anchor"></a><b>&#167;16. </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><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-is2.html#SP1" class="function-link"><span class="function-syntax">InstanceSubjects::to_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><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="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-ks.html#SP3" class="function-link"><span class="function-syntax">KindSubjects::to_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">) &amp;&amp; (</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="SP17" class="paragraph-anchor"></a><b>&#167;17. 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('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">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#SP19" 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-ks.html#SP3" class="function-link"><span class="function-syntax">KindSubjects::to_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-rs.html#SP1" class="function-link"><span class="function-syntax">RelationSubjects::to_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="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">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">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax">, </span><a href="4-is.html#SP13" 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="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="SP18" class="paragraph-anchor"></a><b>&#167;18. </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('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::log_infs_hierarchy</span></span>:<br/><a href="4-is.html#SP7">&#167;7</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#SP18" 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#SP18" 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="SP19" class="paragraph-anchor"></a><b>&#167;19. Methods. </b>The first of these should fill in a name, if one is available, placing the
word range into the wording.
</p>
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">GET_NAME_TEXT_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">GET_NAME_TEXT_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">)</span>
<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('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">InferenceSubjects::get_name_text</span></span>:<br/><a href="4-is.html#SP17">&#167;17</a><br/>Knowledge Module - <a href="1-km.html#SP4">&#167;4</a><br/>Conditions of Subjects - <a href="4-cos.html#SP3_3">&#167;3.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">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="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">GET_NAME_TEXT_INFS_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">W</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="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>The default certainty level is the level assumed in sentences which give
no specific certainty: so it affects "a window is open" but not "a window
is usually open". This depends on the subject rather than the inference,
and in general a subject which is broad will choose to reduce the default
level of certainty.
</p>
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">GET_DEFAULT_CERTAINTY_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">INT_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">GET_DEFAULT_CERTAINTY_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::get_default_certainty</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::get_default_certainty</span></span>:<br/>Inferences - <a href="5-inf.html#SP8_2">&#167;8.2</a><br/>Property Inferences - <a href="5-pi.html#SP2">&#167;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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cert</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">INT_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">cert</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">GET_DEFAULT_CERTAINTY_INFS_MTID</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">cert</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. </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: for example by adding some runtime storage data.
</p>
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">NEW_PERMISSION_GRANTED_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">NEW_PERMISSION_GRANTED_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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="reserved-syntax">property_permission</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pp</span><span class="plain-syntax">)</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::new_permission_granted</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::new_permission_granted</span></span>:<br/>Property Permissions - <a href="4-pp.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">property_permission</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pp</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">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">NEW_PERMISSION_GRANTED_INFS_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">pp</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>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="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">MAKE_ADJ_CONST_DOMAIN_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">MAKE_ADJ_CONST_DOMAIN_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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="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="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::make_adj_const_domain</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::make_adj_const_domain</span></span>:<br/>Instances - <a href="2-ins.html#SP9">&#167;9</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="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">MAKE_ADJ_CONST_DOMAIN_INFS_MTID</span><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="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </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="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">COMPLETE_MODEL_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">COMPLETE_MODEL_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::complete_model</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::complete_model</span></span>:<br/>The Model World - <a href="5-tmw.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">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">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">COMPLETE_MODEL_INFS_MTID</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="SP24" class="paragraph-anchor"></a><b>&#167;24. </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="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">CHECK_MODEL_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">CHECK_MODEL_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::check_model</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::check_model</span></span>:<br/>The Model World - <a href="5-tmw.html#SP4">&#167;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="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">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">CHECK_MODEL_INFS_MTID</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="SP25" class="paragraph-anchor"></a><b>&#167;25. </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="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">EMIT_ELEMENT_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">INT_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">EMIT_ELEMENT_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t0_s</span><span class="plain-syntax">)</span>
<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="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="identifier-syntax">INT_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">written</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">infs_family</span><span class="plain-syntax">, </span><span class="constant-syntax">EMIT_ELEMENT_INFS_MTID</span><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="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">EmitCode::val_true</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>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 firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. </b><span class="extract"><span class="extract-syntax">EMIT_ALL_INFS_MTID</span></span> 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">EMIT_ALL_INFS_MTID</span></span> should return <span class="extract"><span class="extract-syntax">TRUE</span></span> to indicate the former
course. And otherwise, the method <span class="extract"><span class="extract-syntax">EMIT_ONE_INFS_MTID</span></span> should do the job
for an individual subject.
</p>
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">EMIT_ALL_INFS_MTID</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">EMIT_ONE_INFS_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">INT_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">EMIT_ALL_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ignored</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">EMIT_ONE_INFS_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">InferenceSubjects::emit_all</span><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="5-pi.html#SP12" class="function-link"><span class="function-syntax">PropertyInferences::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">inference_subject_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">family</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">family</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject_family</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="identifier-syntax">INT_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">done</span><span class="plain-syntax">, </span><span class="identifier-syntax">family</span><span class="plain-syntax">, </span><span class="constant-syntax">EMIT_ALL_INFS_MTID</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">if</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">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">infs_family</span><span class="plain-syntax"> == </span><span class="identifier-syntax">family</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">family</span><span class="plain-syntax">, </span><span class="constant-syntax">EMIT_ONE_INFS_MTID</span><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="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. Feature data. </b>If a feature is in use, it may need to attach data of its own to a subject,
and the following macro does that. <span class="extract"><span class="extract-syntax">name</span></span> should be the name of the feature,
say <span class="extract"><span class="extract-syntax">spatial</span></span>; <span class="extract"><span class="extract-syntax">creator</span></span> a function to create and initialise the data structure,
returning a pointer to it.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">ATTACH_FEATURE_DATA_TO_SUBJECT</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">val</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">additional_data_for_features</span><span class="plain-syntax">[</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_feature</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">val</span><span class="plain-syntax">);</span>
</pre>
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>&#167;29. </b>Then, to access that same data, the following &mdash; though in practice each
plugin will define further macros to make more abbreviated forms. Many of
the features from the <a href="../if-module/index.html" class="internal">if</a> module are concerned only with instances &mdash; rooms
and doors, say &mdash; so <span class="extract"><span class="extract-syntax">DATA_ON_INSTANCE</span></span>_PCALL pays its way.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">FEATURE_DATA_ON_SUBJECT</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">additional_data_for_features</span><span class="plain-syntax">[</span><span class="identifier-syntax">name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_feature</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">FEATURE_DATA_ON_INSTANCE</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">FEATURE_DATA_ON_SUBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><a href="2-ins.html#SP6" 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>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-cr.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-vs.html">vs</a></li><li class="progresssection"><a href="4-is2.html">is2</a></li><li class="progresssection"><a href="4-ks.html">ks</a></li><li class="progresssection"><a href="4-rs.html">rs</a></li><li class="progresssection"><a href="4-pp.html">pp</a></li><li class="progresssection"><a href="4-cos.html">cos</a></li><li class="progresschapter"><a href="5-inf.html">5</a></li><li class="progressnext"><a href="4-vs.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>