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

456 lines
70 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Instance Counting</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">
<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 'Instance Counting' 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">runtime</a></li><li><a href="index.html#2">Chapter 2: Emission</a></li><li><b>Instance Counting</b></li></ul></div>
<p class="purpose">Though a feature, for convenience of implementation, this code is always active and provides for efficient loops through instances at runtime.</p>
<ul class="toc"><li><a href="2-ic.html#SP1">&#167;1. Feature startup</a></li><li><a href="2-ic.html#SP5">&#167;5. The IK-count</a></li><li><a href="2-ic.html#SP7">&#167;7. The IK-sequence</a></li><li><a href="2-ic.html#SP9">&#167;9. The KD-count</a></li><li><a href="2-ic.html#SP10">&#167;10. Properties of instances</a></li><li><a href="2-ic.html#SP11">&#167;11. Loop optimisation</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Feature startup. </b>Being a feature, this needs a startup function, and here it is. It is in fact
called on every run: see <a href="../core-module/1-cm.html" class="internal">Core Module (in core)</a>.
</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">InstanceCounting::start</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">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">NEW_SUBJECT_NOTIFY_PLUG</span><span class="plain-syntax">, </span><a href="2-ic.html#SP3" class="function-link"><span class="function-syntax">InstanceCounting::counting_new_subject_notify</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">COMPLETE_MODEL_PLUG</span><span class="plain-syntax">, </span><a href="2-ic.html#SP10" class="function-link"><span class="function-syntax">InstanceCounting::counting_complete_model</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">PRODUCTION_LINE_PLUG</span><span class="plain-syntax">, </span><a href="2-ic.html#SP1" class="function-link"><span class="function-syntax">InstanceCounting::production_line</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InstanceCounting::production_line</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stage</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">debugging</span><span class="plain-syntax">, </span><span class="identifier-syntax">stopwatch_timer</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sequence_timer</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">stage</span><span class="plain-syntax"> == </span><span class="identifier-syntax">INTER1_CSEQ</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">BENCH</span><span class="plain-syntax">(</span><a href="2-ic.html#SP8" class="function-link"><span class="function-syntax">InstanceCounting::define_IK_sequence_start_constants</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">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Being a plugin, this code can provide extra data on inference subjects. It
will in practice use that only for subjects representing kinds:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">) </span><span class="identifier-syntax">FEATURE_DATA_ON_SUBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">counting</span><span class="plain-syntax">, </span><span class="identifier-syntax">subj</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">counting_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">has_instances</span><span class="plain-syntax">; </span><span class="comment-syntax"> are there any instances of this kind?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IK_count_prop</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">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_in_IK_sequence_prop</span><span class="plain-syntax">; </span><span class="comment-syntax"> the IK-Link property for this kind</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">counting_data</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure counting_data is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b></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">InstanceCounting::counting_new_subject_notify</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">InstanceCounting::counting_new_subject_notify</span></span>:<br/><a href="2-ic.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ATTACH_FEATURE_DATA_TO_SUBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">counting</span><span class="plain-syntax">, </span><span class="identifier-syntax">subj</span><span class="plain-syntax">, </span><a href="2-ic.html#SP3" class="function-link"><span class="function-syntax">InstanceCounting::new_data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subj</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">counting_data</span><span class="plain-syntax"> *</span><span class="function-syntax">InstanceCounting::new_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">counting_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cd</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">counting_data</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IK_count_prop</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">cd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_in_IK_sequence_prop</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">cd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">has_instances</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><span class="identifier-syntax">cd</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="function-syntax">InstanceCounting::IK_count_property</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">InstanceCounting::IK_count_property</span></span>:<br/>Relations - <a href="5-rlt.html#SP10_2">&#167;10.2</a></span></button><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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::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="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">IK_count_prop</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">P</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-prp.html#SP2" class="function-link"><span class="function-syntax">RTProperties::iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. The IK-count. </b>The IK-count for an instance I of kind K is the result of numbering instances
of that kind upwards from 0. This depends on both I and K, hence the name:
for example, a red car might be thing number 17 but vehicle number 2. Within
each kind, instances are numbered in creation order by the source text.
</p>
<p class="commentary">Before we can store this, we must calculate it, which we do with this less
than elegant two-dimensional array:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">INSTANCE_COUNT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_instance_counts</span><span class="plain-syntax">[(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">*</span><span class="identifier-syntax">max_kind_instance_count</span><span class="plain-syntax"> +</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Behaviour::get_range_number</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)]</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_instance_counts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_kind_instance_count</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">InstanceCounting::calculate_IK_counts</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">InstanceCounting::calculate_IK_counts</span></span>:<br/><a href="2-ic.html#SP10">&#167;10</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="named-paragraph-container code-font"><a href="2-ic.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Allocate the instance count array in memory</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Compute the instance count array</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Allocate the instance count array in memory</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">max_kind_instance_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_instance_counts</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Memory::calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">max_kind_instance_count</span><span class="plain-syntax">*</span><span class="identifier-syntax">max_kind_instance_count</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">INSTANCE_COUNTING_MREASON</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b>The following is quadratic in the number of objects, but this has never been
a problem in practice; the number seldom exceeds a few hundred.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute the instance count array</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">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="identifier-syntax">LOOP_OVER_BASE_KINDS</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">INSTANCE_COUNT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">) = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ix_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">INSTANCE_COUNT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">) = </span><span class="identifier-syntax">ix_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Instance counts are actually useful to several other features, so we provide
the following. Note that if I is not in fact an instance of K then its IK-count
is by definition -1.
</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">InstanceCounting::IK_count</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kind_instance_counts</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">"instance counts not available"</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">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"instance counts available only for objects"</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">INSTANCE_COUNT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. The IK-sequence. </b>Within each kind K, we form the instances in a linked list called the "IK-sequence".
Again, the list position of I depends on K: the red car might be in one position
in the list of things, and another in the list of vehicles.
</p>
<p class="commentary">This sequence will be in "declaration order", that is, it will match the order
in which instances are declared in Inter. This is not the same as their creation
order in Inform 7 source text, though it tends to be roughly similar.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
</p>
<p class="commentary">The following function abstracts the list, returning the first instance if <span class="extract"><span class="extract-syntax">I</span></span>
is <span class="extract"><span class="extract-syntax">NULL</span></span>, and otherwise the next after <span class="extract"><span class="extract-syntax">I</span></span>. Note that it excludes instances which
have been "diverted".<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</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> Declaration order is more trouble to arrange, but we do it so that an optimised
and an unoptimised loop to perform the same search will not only iterate through
the same set of objects, but in the same order.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li><li class="footnote" id="fn:2"><p class="inwebfootnote"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> This is used to get rid of the <span class="extract"><span class="extract-syntax">selfobj</span></span> object in cases where the source text
creates an explicit player.
<a href="#fnref:2" title="return to text"> &#x21A9;</a></p></li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="function-syntax">InstanceCounting::next_in_IK_sequence</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">InstanceCounting::next_in_IK_sequence</span></span>:<br/><a href="2-ic.html#SP8">&#167;8</a>, <a href="2-ic.html#SP10_4_2">&#167;10.4.2</a><br/>List Literals - <a href="4-ll.html#SP7_1">&#167;7.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</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="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">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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">resuming</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">if</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="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FIRST_IN_INSTANCE_ORDERING</span><span class="plain-syntax">; </span><span class="identifier-syntax">resuming</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">resuming</span><span class="plain-syntax">) </span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEXT_IN_INSTANCE_ORDERING</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">resuming</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">if</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="reserved-syntax">break</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">InferenceSubjects::aliased_but_diverted</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">selfobj</span></span><span class="comment-syntax"> may not count</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</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">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>At runtime, we will store the IK sequences by defining their first entries
as constants,<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> and their subsequent entries as property values of instances.
The constants are declared here, and see <a href="2-ic.html#SP10" class="internal">InstanceCounting::counting_complete_model</a>
below for the properties.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:3"><p class="inwebfootnote"><sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> We don't need to store these list origins in some table in memory at
runtime because Inform always compiles code which knows which kind it's looping
over: so it never needs to look up an IK-sequence where K is not known at
compile time.
<a href="#fnref:3" title="return to text"> &#x21A9;</a></p></li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">InstanceCounting::define_IK_sequence_start_constants</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">InstanceCounting::define_IK_sequence_start_constants</span></span>:<br/><a href="2-ic.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="identifier-syntax">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="identifier-syntax">LOOP_OVER_BASE_KINDS</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iname</span><span class="plain-syntax"> = </span><a href="5-kc.html#SP10" class="function-link"><span class="function-syntax">RTKindConstructors::first_instance_iname</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="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax"> = </span><a href="2-ic.html#SP7" class="function-link"><span class="function-syntax">InstanceCounting::next_in_IK_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-emt.html#SP8" class="function-link"><span class="function-syntax">Emit::iname_constant</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><a href="5-ins.html#SP1" class="function-link"><span class="function-syntax">RTInstances::value_iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">next</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><a href="2-emt.html#SP8" class="function-link"><span class="function-syntax">Emit::iname_constant</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</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="SP9" class="paragraph-anchor"></a><b>&#167;9. The KD-count. </b>This section is supposedly for instance-counting, but it also does a little
kind-counting: specifically we number the subkinds of object. The KD-count of a
kind is this number.<sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup>
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:4"><p class="inwebfootnote"><sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup> I have completely forgotten what the D stood for. KD-counts are in creation
order, not declaration order, so it can't be D for declaration.
<a href="#fnref:4" title="return to text"> &#x21A9;</a></p></li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InstanceCounting::KD_count</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">InstanceCounting::KD_count</span></span>:<br/><a href="2-ic.html#SP10_3">&#167;10.3</a></span></button><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="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="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">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IK</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">IK</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">IK</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">IK</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">c</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="constant-syntax">0</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. Properties of instances. </b>At model completion time, then, we assign a set of low-level properties to
all the object instances. These consume memory without even being visible in
Inform 7 source text: they are all basically optimisations, and are a classic
trade-off of memory for speed. For the most part we care more about memory in
the Inform runtime (one of our target VMs has a very low memory ceiling), but
search loops must run as fast as they possibly can.
</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">InstanceCounting::counting_complete_model</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">InstanceCounting::counting_complete_model</span></span>:<br/><a href="2-ic.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stage</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">stage</span><span class="plain-syntax"> == </span><span class="identifier-syntax">WORLD_STAGE_I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Create and assert zero values of the vector property</span><span class="named-paragraph-number">10.1</span></a></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">stage</span><span class="plain-syntax"> == </span><span class="identifier-syntax">WORLD_STAGE_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_KD_Count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"KD_Count"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP10_2" class="named-paragraph-link"><span class="named-paragraph">Create the two instance properties for each kind of object</span><span class="named-paragraph-number">10.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-ic.html#SP5" class="function-link"><span class="function-syntax">InstanceCounting::calculate_IK_counts</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP10_3" class="named-paragraph-link"><span class="named-paragraph">Assert the KD count property for I</span><span class="named-paragraph-number">10.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP10_4" class="named-paragraph-link"><span class="named-paragraph">Assert values of the two instance properties for I</span><span class="named-paragraph-number">10.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_1" class="paragraph-anchor"></a><b>&#167;10.1. </b>The <span class="extract"><span class="extract-syntax">vector</span></span> property provides workspace for the relation-route-finding code
at runtime: it doesn't actually have anything to do with instance counting as
such, but then again it doesn't deserve its own section of code.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create and assert zero values of the vector property</span><span class="named-paragraph-number">10.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_vector</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"vector"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</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">zero</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::from_int</span><span class="plain-syntax">(0, </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_vector</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">zero</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_2" class="paragraph-anchor"></a><b>&#167;10.2. </b>For each subkind of object K to which an instance I belongs, we will store the
IK-count in a numerical property. So the red car, for example, would be given two
property values: one for (red car, thing), one for (red car, vehicle). The
properties in question are the <span class="extract"><span class="extract-syntax">IK_count_prop</span></span> for thing and vehicle.
</p>
<p class="commentary">Similarly for the next terms in the IK-sequences.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create the two instance properties for each kind of object</span><span class="named-paragraph-number">10.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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="identifier-syntax">LOOP_OVER_BASE_KINDS</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::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="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">count_iname</span><span class="plain-syntax"> = </span><a href="5-kc.html#SP11" class="function-link"><span class="function-syntax">RTKindConstructors::base_IK_iname</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="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">IK_count_prop</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ValueProperties::new_nameless_using</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_number</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="5-kc.html#SP2" class="function-link"><span class="function-syntax">RTKindConstructors::kind_package</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">), </span><span class="identifier-syntax">count_iname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_iname</span><span class="plain-syntax"> = </span><a href="5-kc.html#SP10" class="function-link"><span class="function-syntax">RTKindConstructors::next_instance_iname</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="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">next_in_IK_sequence_prop</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ValueProperties::new_nameless_using</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="5-kc.html#SP2" class="function-link"><span class="function-syntax">RTKindConstructors::kind_package</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">), </span><span class="identifier-syntax">next_iname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_3" class="paragraph-anchor"></a><b>&#167;10.3. </b>For any object instance, the property <span class="extract"><span class="extract-syntax">KD_Count</span></span> holds the KD-count for its
immediate kind. For a red car which was both vehicle and thing, therefore, this
would be the number for "vehicle", not for "thing".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert the KD count property for I</span><span class="named-paragraph-number">10.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ic</span><span class="plain-syntax"> = </span><a href="2-ic.html#SP9" class="function-link"><span class="function-syntax">InstanceCounting::KD_count</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::to_kind</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">the_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::from_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">ic</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">ValueProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P_KD_Count</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">the_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4" class="paragraph-anchor"></a><b>&#167;10.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert values of the two instance properties for I</span><span class="named-paragraph-number">10.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::to_kind</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">infs</span><span class="plain-syntax">; </span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::narrowest_broader_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><span class="identifier-syntax">KindSubjects::to_kind</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">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="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::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="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">has_instances</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP10_4_1" class="named-paragraph-link"><span class="named-paragraph">Fill in this IK-count property</span><span class="named-paragraph-number">10.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-ic.html#SP10_4_2" class="named-paragraph-link"><span class="named-paragraph">Fill in this IK-sequence property</span><span class="named-paragraph-number">10.4.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4_1" class="paragraph-anchor"></a><b>&#167;10.4.1. </b>And otherwise, for every kind that the instance belongs to (directly or
indirectly) it gets the relevant instance count as a property value. For
example, the red door might have <span class="extract"><span class="extract-syntax">IK4_Count</span></span> set to 3 &mdash; it's door number 3,
let's suppose &mdash; and <span class="extract"><span class="extract-syntax">IK2_Count</span></span> set to 19 &mdash; it's thing number 19. It doesn't
have an <span class="extract"><span class="extract-syntax">IK7_Count</span></span> property at all, since it isn't a backdrop (kind number 7),
and so on for all other kinds.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fill in this IK-count property</span><span class="named-paragraph-number">10.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ic</span><span class="plain-syntax"> = </span><span class="identifier-syntax">INSTANCE_COUNT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</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">the_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::from_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">ic</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">ValueProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">IK_count_prop</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">the_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP10_4">&#167;10.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4_2" class="paragraph-anchor"></a><b>&#167;10.4.2. </b>The IK-Link property is never set for kind 0, so there's no special case. It
records the next instance in compilation order:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fill in this IK-sequence property</span><span class="named-paragraph-number">10.4.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax"> = </span><a href="2-ic.html#SP7" class="function-link"><span class="function-syntax">InstanceCounting::next_in_IK_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</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><span class="identifier-syntax">next</span><span class="plain-syntax">)?</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::from_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">next</span><span class="plain-syntax">):</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::new_nothing_object_constant</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">next_in_IK_sequence_prop</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">val</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-ic.html#SP10_4">&#167;10.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Loop optimisation. </b>Lastly, then, the coup de grace: here's where we define loop schemas to
perform loops through kinds quickly at run-time. We start from the First
constants, and use the Next constants to progress; and we stop at <span class="extract"><span class="extract-syntax">nothing</span></span>.
</p>
<p class="commentary">There is no actual need to compile the schema differently in the case of
an empty loop, where there are no instances of the kind <span class="extract"><span class="extract-syntax">K</span></span> to loop over:
the regular schema would work fine. But it would make the code somehow
misleading to a human reader.
</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">InstanceCounting::optimise_loop</span><span class="plain-syntax">(</span><span class="identifier-syntax">i6_schema</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sch</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_INACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">counting</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="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">COUNTING_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">has_instances</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">Calculus::Schemas::modify</span><span class="plain-syntax">(</span><span class="identifier-syntax">sch</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for (*1=nothing: false: )"</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="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_iname</span><span class="plain-syntax"> = </span><a href="5-kc.html#SP10" class="function-link"><span class="function-syntax">RTKindConstructors::first_instance_iname</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="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_iname</span><span class="plain-syntax"> = </span><a href="5-kc.html#SP10" class="function-link"><span class="function-syntax">RTKindConstructors::next_instance_iname</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="identifier-syntax">Calculus::Schemas::modify</span><span class="plain-syntax">(</span><span class="identifier-syntax">sch</span><span class="plain-syntax">, </span><span class="string-syntax">"for (*1=%n: *1: *1=*1.%n)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_iname</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">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-es.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-rm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-hrr.html">hrr</a></li><li class="progresssection"><a href="2-ni.html">ni</a></li><li class="progresssection"><a href="2-cu.html">cu</a></li><li class="progresssection"><a href="2-emt.html">emt</a></li><li class="progresssection"><a href="2-ec.html">ec</a></li><li class="progresssection"><a href="2-ea.html">ea</a></li><li class="progresssection"><a href="2-int.html">int</a></li><li class="progresssection"><a href="2-sv.html">sv</a></li><li class="progresssection"><a href="2-th.html">th</a></li><li class="progresssection"><a href="2-dv.html">dv</a></li><li class="progresssection"><a href="2-es.html">es</a></li><li class="progresscurrent">ic</li><li class="progresssection"><a href="2-kd.html">kd</a></li><li class="progresssection"><a href="2-sc.html">sc</a></li><li class="progresssection"><a href="2-hnae.html">hnae</a></li><li class="progresssection"><a href="2-sn.html">sn</a></li><li class="progresssection"><a href="2-gpr.html">gpr</a></li><li class="progresssection"><a href="2-ie.html">ie</a></li><li class="progresschapter"><a href="3-gm.html">3</a></li><li class="progresschapter"><a href="4-enc.html">4</a></li><li class="progresschapter"><a href="5-act.html">5</a></li><li class="progresschapter"><a href="6-bd.html">6</a></li><li class="progresschapter"><a href="7-cg.html">7</a></li><li class="progressnext"><a href="2-kd.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>