1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/core-module/6-rlt.html
2019-09-01 11:50:12 +01:00

3596 lines
520 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>6/bp</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '6/rlt' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#6">Chapter 6: Verbs</a></li><li><b>Relations</b></li></ul><p class="purpose">What Inform internally calls "binary predicates", the user calls "relations". In this section, we parse definitions of new relations and create the resulting |binary_predicate| objects.</p>
<ul class="toc"><li><a href="#SP2">&#167;2. Built-in relation names</a></li><li><a href="#SP4">&#167;4. Creation, Stage I</a></li><li><a href="#SP9">&#167;9. Creation, Stage II</a></li><li><a href="#SP9_2">&#167;9.2. The parsing phase</a></li><li><a href="#SP9_5">&#167;9.5. The completion phase</a></li><li><a href="#SP10">&#167;10. Storing relations</a></li><li><a href="#SP11">&#167;11. Parsing utilities</a></li><li><a href="#SP13">&#167;13. Relation records</a></li><li><a href="#SP17">&#167;17. Support for the RELATIONS command</a></li><li><a href="#SP18">&#167;18. The bitmap for various-to-various relations</a></li><li><a href="#SP23">&#167;23. The partition for an equivalence relation</a></li><li><a href="#SP28">&#167;28. Checking correctness of 1-to-1 relations</a></li><li><a href="#SP29">&#167;29. Generating routines to test relations by condition</a></li><li><a href="#SP31">&#167;31. Indexing relations</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>The following provides for run-time checking to make sure relations are
not used with the wrong kinds of object. (Compile-time checking excludes
other cases.)
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">relation_guard</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">guarding</span><span class="plain">; </span> <span class="comment">which one is being defended</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">check_L</span><span class="plain">; </span> <span class="comment">or null if no check needed</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">check_R</span><span class="plain">; </span> <span class="comment">or null if no check needed</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">inner_test</span><span class="plain">; </span> <span class="comment">schemas for the relation if check passes</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">inner_make_true</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">inner_make_false</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">f0</span><span class="plain">; </span> <span class="comment">schemas for the relation's function</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">f1</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">guard_f0_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">guard_f1_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">guard_test_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">guard_make_true_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">guard_make_false_iname</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">relation_guard</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure relation_guard is private to this section.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Built-in relation names. </b>These have to be defined somewhere, and it may as well be here.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">EQUALITY_RELATION_NAME</span><span class="plain"> 0</span>
<span class="definitionkeyword">define</span> <span class="constant">UNIVERSAL_RELATION_NAME</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">MEANING_RELATION_NAME</span><span class="plain"> 2</span>
<span class="definitionkeyword">define</span> <span class="constant">PROVISION_RELATION_NAME</span><span class="plain"> 3</span>
<span class="definitionkeyword">define</span> <span class="constant">GE_RELATION_NAME</span><span class="plain"> 4</span>
<span class="definitionkeyword">define</span> <span class="constant">GT_RELATION_NAME</span><span class="plain"> 5</span>
<span class="definitionkeyword">define</span> <span class="constant">LE_RELATION_NAME</span><span class="plain"> 6</span>
<span class="definitionkeyword">define</span> <span class="constant">LT_RELATION_NAME</span><span class="plain"> 7</span>
<span class="definitionkeyword">define</span> <span class="constant">ADJACENCY_RELATION_NAME</span><span class="plain"> 8</span>
<span class="definitionkeyword">define</span> <span class="constant">REGIONAL_CONTAINMENT_RELATION_NAME</span><span class="plain"> 9</span>
<span class="definitionkeyword">define</span> <span class="constant">CONTAINMENT_RELATION_NAME</span><span class="plain"> 10</span>
<span class="definitionkeyword">define</span> <span class="constant">SUPPORT_RELATION_NAME</span><span class="plain"> 11</span>
<span class="definitionkeyword">define</span> <span class="constant">INCORPORATION_RELATION_NAME</span><span class="plain"> 12</span>
<span class="definitionkeyword">define</span> <span class="constant">CARRYING_RELATION_NAME</span><span class="plain"> 13</span>
<span class="definitionkeyword">define</span> <span class="constant">HOLDING_RELATION_NAME</span><span class="plain"> 14</span>
<span class="definitionkeyword">define</span> <span class="constant">WEARING_RELATION_NAME</span><span class="plain"> 15</span>
<span class="definitionkeyword">define</span> <span class="constant">POSSESSION_RELATION_NAME</span><span class="plain"> 16</span>
<span class="definitionkeyword">define</span> <span class="constant">VISIBILITY_RELATION_NAME</span><span class="plain"> 17</span>
<span class="definitionkeyword">define</span> <span class="constant">TOUCHABILITY_RELATION_NAME</span><span class="plain"> 18</span>
<span class="definitionkeyword">define</span> <span class="constant">CONCEALMENT_RELATION_NAME</span><span class="plain"> 19</span>
<span class="definitionkeyword">define</span> <span class="constant">ENCLOSURE_RELATION_NAME</span><span class="plain"> 20</span>
<span class="definitionkeyword">define</span> <span class="constant">ROOM_CONTAINMENT_RELATION_NAME</span><span class="plain"> 21</span>
</pre>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>These are the English names of the built-in relations. The use of hyphenation
here is a fossil from the times when Inform allowed only single-word relation
names; but it doesn't seem worth changing, especially as the hyphenated
relations are almost never needed for anything. All the same, translators into
other languages may as well drop the hyphens.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">names</span><span class="plain">&gt; ::=</span>
<span class="identifier">equality</span><span class="plain"> |</span>
<span class="identifier">universal</span><span class="plain"> |</span>
<span class="identifier">meaning</span><span class="plain"> |</span>
<span class="identifier">provision</span><span class="plain"> |</span>
<span class="identifier">numerically</span><span class="plain">-</span><span class="identifier">greater</span><span class="plain">-</span><span class="identifier">than</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">equal</span><span class="plain">-</span><span class="identifier">to</span><span class="plain"> |</span>
<span class="identifier">numerically</span><span class="plain">-</span><span class="identifier">greater</span><span class="plain">-</span><span class="identifier">than</span><span class="plain"> |</span>
<span class="identifier">numerically</span><span class="plain">-</span><span class="identifier">less</span><span class="plain">-</span><span class="identifier">than</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">equal</span><span class="plain">-</span><span class="identifier">to</span><span class="plain"> |</span>
<span class="identifier">numerically</span><span class="plain">-</span><span class="identifier">less</span><span class="plain">-</span><span class="identifier">than</span><span class="plain"> |</span>
<span class="identifier">adjacency</span><span class="plain"> |</span>
<span class="identifier">regional</span><span class="plain">-</span><span class="identifier">containment</span><span class="plain"> |</span>
<span class="identifier">containment</span><span class="plain"> |</span>
<span class="identifier">support</span><span class="plain"> |</span>
<span class="identifier">incorporation</span><span class="plain"> |</span>
<span class="identifier">carrying</span><span class="plain"> |</span>
<span class="identifier">holding</span><span class="plain"> |</span>
<span class="identifier">wearing</span><span class="plain"> |</span>
<span class="identifier">possession</span><span class="plain"> |</span>
<span class="identifier">visibility</span><span class="plain"> |</span>
<span class="identifier">touchability</span><span class="plain"> |</span>
<span class="identifier">concealment</span><span class="plain"> |</span>
<span class="identifier">enclosure</span><span class="plain"> |</span>
<span class="identifier">room</span><span class="plain">-</span><span class="identifier">containment</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Creation, Stage I. </b>The creation of relations happens in two stages. First, when the parse tree is
being organised into sentences, we call the following routine the moment a
relation definition has been found. (This is important because it may affect
the parsing of subsequent sentences in the source text.) The predicate we make
is initially sketchy: but by existing, and having a name, it can be used in
subsequent verb definitions, and then subsequent sentences using those newly
defined verbs can be properly parsed all during the same run-through of the
parse tree.
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>This handles the special meaning "X relates Y to Z".
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt; </span><span class="identifier">to</span><span class="plain"> &lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt; ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]; ((</span><span class="identifier">parse_node</span><span class="plain"> *) </span><span class="identifier">RP</span><span class="plain">[1])-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::new_relation_SMF</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">NPs</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[0]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">OW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[1]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">task</span><span class="plain">) { </span> <span class="comment">"Knowledge relates various people to various things."</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ACCEPT_SMFT</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">OW</span><span class="plain">)) {</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">, </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">O</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt;(</span><span class="identifier">SW</span><span class="plain">);</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">O</span><span class="plain">;</span>
<span class="functiontext">Relations::parse_new</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TRAVERSE1_SMFT</span><span class="plain">:</span>
<span class="functiontext">Relations::parse_new_relation_further</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::new_relation_SMF is used in 6/nv (<a href="6-nv.html#SP16">&#167;16</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The following grammar is used to parse the subject noun phrase of
sentences like
</p>
<blockquote>
<p>Acquaintance relates people to each other.</p>
</blockquote>
<p class="inwebparagraph">Since the point is to create something new, the only stipulation is that the
text of the subject mustn't be an existing relation name.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">subject</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_RelationExists problem</span> <span class="cwebmacronumber">7.1</span>&gt;
<span class="plain">... ==&gt; </span><span class="identifier">TRUE</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_RelationExists problem</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelationExists</span><span class="plain">),</span>
<span class="string">"that relation already exists"</span><span class="plain">,</span>
<span class="string">"and cannot have its definition amended now."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::parse_new</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">) {</span>
<span class="plain">&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">subject</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">);</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Wordings::truncate</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, 31);</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::make_pair_sketchily</span><span class="plain">(</span>
<span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="constant">Relation_OtoO</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_new_relation_here</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::parse_new is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Creation, Stage II. </b>In the second stage, which is reached during the first traverse of
sentences to work through the assertions, we parse the specification of the
relation properly and complete the BP structure. (In the interim period,
the name of the BP is really the only thing that has been used.)
</p>
<p class="inwebparagraph">Altogether, the Inform user is allowed to define some eight different forms
of relation. The code below is an attempt to find whatever common ground
can be found from these different outcomes, but inevitably ends up
splitting into cases.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::parse_new_relation_further</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">RW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">); </span> <span class="comment">relation name</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">FW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">); </span> <span class="comment">left term declaration, before "to"</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">); </span> <span class="comment">right term declaration, after "to"</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">ParseTree::get_new_relation_here</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">; </span> <span class="comment">to recover from problem</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bpr</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">used for run-time storage of this relation</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">i6_prn_name</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">the I6 identifier for this property</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">storage_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">what kind, if any, might be stored in it</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">storage_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">summing these up</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">left_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">right_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">kind requirement</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CONW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">; </span> <span class="comment">text of test condition if any</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">, </span> <span class="comment"><code class="display"><span class="extract">TRUE</span></code> for one, <code class="display"><span class="extract">FALSE</span></code> for various,</span>
<span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">, </span> <span class="comment">...or <code class="display"><span class="extract">NOT_APPLICABLE</span></code> for unspecified</span>
<span class="identifier">symmetric</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span> <span class="comment">a symmetric relation?</span>
<span class="identifier">equivalence</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span> <span class="comment">an equivalence ("in groups") relation?</span>
<span class="identifier">rvno</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span> <span class="comment">relate values not objects?</span>
<span class="identifier">frf</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span> <span class="comment">use fast route-finding?</span>
<span class="identifier">dynamic</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span> <span class="comment">use dynamic memory allocation for storage?</span>
<span class="identifier">provide_prn</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span> <span class="comment">allocate the storage property to the kind?</span>
<span class="identifier">calling_made</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">one of the terms has been given a name</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"BP in relation not initially parsed"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">RW</span><span class="plain">) &gt; </span><span class="identifier">MAX_WORDS_IN_ASSEMBLAGE</span><span class="plain">-4) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelationNameTooLong</span><span class="plain">),</span>
<span class="string">"this is too long a name for a single relation to have"</span><span class="plain">,</span>
<span class="string">"and would become unwieldy."</span><span class="plain">);</span>
<span class="identifier">RW</span><span class="plain"> = </span><span class="identifier">Wordings::truncate</span><span class="plain">(</span><span class="identifier">RW</span><span class="plain">, </span><span class="identifier">MAX_WORDS_IN_ASSEMBLAGE</span><span class="plain">-4);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Parse the classification variables and use them to fill in the BP term details</span> <span class="cwebmacronumber">9.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rvno</span><span class="plain">) { </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relates_values_not_objects</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;relates_values_not_objects</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">frf</span><span class="plain">) { </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;fast_route_finding</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;fast_route_finding</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain">) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;i6_storage_property</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">; </span><span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;i6_storage_property</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">;</span>
<span class="functiontext">Properties::Valued::set_stored_relation</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dynamic</span><span class="plain">) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;dynamic_memory</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;dynamic_memory</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;initialiser_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">RELATION_INITIALISER_FN_HL</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">BinaryPredicates::mark_as_needed</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">CONW</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Complete as a relation-by-routine BP</span> <span class="cwebmacronumber">9.13</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">equivalence</span><span class="plain">) </span>&lt;<span class="cwebmacro">Complete as an equivalence-relation BP</span> <span class="cwebmacronumber">9.12</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_unique</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_unique</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">symmetric</span><span class="plain">) </span>&lt;<span class="cwebmacro">Complete as a symmetric one-to-one BP</span> <span class="cwebmacronumber">9.10</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Complete as an asymmetric one-to-one BP</span> <span class="cwebmacronumber">9.6</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Complete as a one-to-various BP</span> <span class="cwebmacronumber">9.7</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_unique</span><span class="plain">) </span>&lt;<span class="cwebmacro">Complete as a various-to-one BP</span> <span class="cwebmacronumber">9.8</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">symmetric</span><span class="plain">) </span>&lt;<span class="cwebmacro">Complete as a symmetric various-to-various BP</span> <span class="cwebmacronumber">9.11</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Complete as an asymmetric various-to-various BP</span> <span class="cwebmacronumber">9.9</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dynamic</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">calling_made</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem message since this won't be stored in a property</span> <span class="cwebmacronumber">9.4</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Override with dynamic allocation schemata</span> <span class="cwebmacronumber">9.15</span>&gt;<span class="plain">;</span>
<span class="functiontext">Kinds::RunTime::ensure_basic_heap_present</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">provide_prn</span><span class="plain">)</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span>
<span class="functiontext">Calculus::Propositions::Abstract::to_provide_property</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">), </span><span class="identifier">storage_infs</span><span class="plain">, </span><span class="identifier">prevailing_mood</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Add in the reducing functions</span> <span class="cwebmacronumber">9.14</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) || (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))) {</span>
<span class="reserved">relation_guard</span><span class="plain"> *</span><span class="identifier">rg</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">relation_guard</span><span class="plain">);</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain"> = </span><span class="identifier">left_kind</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain"> = </span><span class="identifier">right_kind</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_test</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_make_true</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_make_false</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guarding</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f0</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_function</span><span class="plain">(&amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0]));</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f1</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_function</span><span class="plain">(&amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1]));</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f0_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f1_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_test_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_true_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_false_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f0</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f0_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">GUARD_F0_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="functiontext">BinaryPredicates::set_term_function</span><span class="plain">(&amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0]),</span>
<span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(%n(*1))"</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f0_iname</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f1</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f1_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">GUARD_F1_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="functiontext">BinaryPredicates::set_term_function</span><span class="plain">(&amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1]),</span>
<span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(%n(*1))"</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f1_iname</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_test_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">GUARD_TEST_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(%n(*1,*2))"</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_test_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_true_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">GUARD_MAKE_TRUE_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(%n(*1,*2))"</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_true_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_false_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">GUARD_MAKE_FALSE_INAME_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(%n(*1,*2))"</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_false_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RELATION_DEFINITIONS</span><span class="plain">, </span><span class="string">"Defined the binary predicate:\</span><span class="plain">n</span><span class="string">$2\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::parse_new_relation_further is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>The following grammar is used to parse the declaration of new relations in
sentences like
</p>
<blockquote>
<p>Acquaintance relates people to each other.</p>
</blockquote>
<p class="inwebparagraph">In such a sentence, we'll call "people" the left object noun phrase and
"each other" the right object noun phrase. The way &lt;relation-term-basic&gt;
is written below, it seems to match any text, but that's just an implementation
convenience; the <code class="display"><span class="extract">...</span></code> text will eventually have to match &lt;k-kind&gt; and thus
to be the name of a kind, possibly in the plural.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">left</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">basic</span><span class="plain">&gt; ( </span><span class="identifier">called</span><span class="plain"> ... ) | ==&gt; </span><span class="identifier">R</span><span class="plain">[1] | </span><span class="constant">CALLED_RBIT</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">basic</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">&gt; </span><span class="identifier">with</span><span class="plain"> </span><span class="identifier">fast</span><span class="plain"> </span><span class="identifier">route</span><span class="plain">-</span><span class="identifier">finding</span><span class="plain"> | ==&gt; </span><span class="identifier">R</span><span class="plain">[1] | </span><span class="constant">FRF_RBIT</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">&gt; </span><span class="identifier">when</span><span class="plain"> ... | ==&gt; </span><span class="identifier">R</span><span class="plain">[1] | </span><span class="constant">WHEN_RBIT</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">&gt; ( </span><span class="identifier">called</span><span class="plain"> ... ) | ==&gt; </span><span class="identifier">R</span><span class="plain">[1] | </span><span class="constant">CALLED_RBIT</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">&gt; ::=</span>
<span class="plain">{</span><span class="identifier">another</span><span class="plain">} | ==&gt; </span><span class="constant">ANOTHER_RBIT</span>
<span class="plain">{</span><span class="identifier">each</span><span class="plain"> </span><span class="identifier">other</span><span class="plain">} | ==&gt; </span><span class="constant">EACHOTHER_RBIT</span>
<span class="plain">{</span><span class="identifier">each</span><span class="plain"> </span><span class="identifier">other</span><span class="plain"> </span><span class="identifier">in</span><span class="plain"> </span><span class="identifier">groups</span><span class="plain">} | ==&gt; </span><span class="constant">GROUPS_RBIT</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">basic</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">basic</span><span class="plain">&gt; ::=</span>
<span class="identifier">one</span><span class="plain"> ... | ==&gt; </span><span class="constant">ONE_RBIT</span>
<span class="identifier">various</span><span class="plain"> ... | ==&gt; </span><span class="constant">VAR_RBIT</span>
<span class="plain">... ==&gt; 0</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. The parsing phase. </b>Our aims here are:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(i) to decide if the definition is valid, and reject it with a suitable
problem message if not, returning from the current routine;
</li><li>(ii) to fill in the classification variables <code class="display"><span class="extract">left_unique</span></code>, <code class="display"><span class="extract">symmetric</span></code>, etc.,
as defined above;
</li><li>(iii) to choose a property which will provide run-time storage for this
relation, if it needs any; and
</li><li>(iv) to set <code class="display"><span class="extract">bp-&gt;term_details[0]</span></code> and <code class="display"><span class="extract">...[1]</span></code> with the kinds, names and
logical properties of the two terms of the BP being defined.
</li></ul>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">FRF_RBIT</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">ONE_RBIT</span><span class="plain"> 2</span>
<span class="definitionkeyword">define</span> <span class="constant">VAR_RBIT</span><span class="plain"> 4</span>
<span class="definitionkeyword">define</span> <span class="constant">ANOTHER_RBIT</span><span class="plain"> 8</span>
<span class="definitionkeyword">define</span> <span class="constant">EACHOTHER_RBIT</span><span class="plain"> 16</span>
<span class="definitionkeyword">define</span> <span class="constant">GROUPS_RBIT</span><span class="plain"> 32</span>
<span class="definitionkeyword">define</span> <span class="constant">WHEN_RBIT</span><span class="plain"> 64</span>
<span class="definitionkeyword">define</span> <span class="constant">CALLED_RBIT</span><span class="plain"> 128</span>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse the classification variables and use them to fill in the BP term details</span> <span class="cwebmacronumber">9.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RELATION_DEFINITIONS</span><span class="plain">,</span>
<span class="string">"Relation definition of %W: left term: '%W', right term: '%W'\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">RW</span><span class="plain">, </span><span class="identifier">FW</span><span class="plain">, </span><span class="identifier">SW</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">LCALLW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">; </span> <span class="comment">left term "calling" name</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">RCALLW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">; </span> <span class="comment">right term "calling" name</span>
<span class="plain">&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">left</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">FW</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">left_bitmap</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_bitmap</span><span class="plain"> &amp; </span><span class="constant">CALLED_RBIT</span><span class="plain">) </span><span class="identifier">LCALLW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">left</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;, 1);</span>
<span class="identifier">FW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">basic</span><span class="plain">&gt;, 1);</span>
<span class="plain">&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">SW</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">right_bitmap</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">CALLED_RBIT</span><span class="plain">) </span><span class="identifier">RCALLW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">&gt;, 1);</span>
<span class="identifier">SW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">term</span><span class="plain">-</span><span class="identifier">basic</span><span class="plain">&gt;, 1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">WHEN_RBIT</span><span class="plain">)</span>
<span class="identifier">CONW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">relates</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">right</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;, 1);</span>
&lt;<span class="cwebmacro">Find term multiplicities and use of fast route-finding</span> <span class="cwebmacronumber">9.3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Detect use of a condition for a test-only relation</span> <span class="cwebmacronumber">9.3.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Detect callings for the terms of the relation</span> <span class="cwebmacronumber">9.3.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Detect use of symmetry in definition of second term</span> <span class="cwebmacronumber">9.3.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Vet the use of callings for the terms of the relation</span> <span class="cwebmacronumber">9.3.6</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Work out the kinds of the terms in the relation</span> <span class="cwebmacronumber">9.3.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_unique</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) {</span>
<span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">LCALLW</span><span class="plain">)) || (</span><span class="identifier">right_unique</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_unique</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) {</span>
<span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">RCALLW</span><span class="plain">)) || (</span><span class="identifier">left_unique</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">CONW</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Determine property used for run-time storage</span> <span class="cwebmacronumber">9.3.8</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Fill in the BP term details based on the left- and right- variables</span> <span class="cwebmacronumber">9.3.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_1"></a><b>&#167;9.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Fill in the BP term details based on the left- and right- variables</span> <span class="cwebmacronumber">9.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">left_bptd</span><span class="plain">, </span><span class="identifier">right_bptd</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">left_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">right_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_kind</span><span class="plain">) </span><span class="identifier">left_infs</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_kind</span><span class="plain">) </span><span class="identifier">right_infs</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">);</span>
<span class="identifier">left_bptd</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::full_new_term</span><span class="plain">(</span><span class="identifier">left_infs</span><span class="plain">, </span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">LCALLW</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">right_bptd</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::full_new_term</span><span class="plain">(</span><span class="identifier">right_infs</span><span class="plain">, </span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">RCALLW</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0] = </span><span class="identifier">left_bptd</span><span class="plain">; </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1] = </span><span class="identifier">right_bptd</span><span class="plain">;</span>
<span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0] = </span><span class="identifier">right_bptd</span><span class="plain">; </span><span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1] = </span><span class="identifier">left_bptd</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_2"></a><b>&#167;9.3.2. </b>We set word ranges for the condition (if any) and the callings (if any),
whittling down the word ranges for the left and right specifications if
these are clipped away, and also look at the multiplicities.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Find term multiplicities and use of fast route-finding</span> <span class="cwebmacronumber">9.3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_bitmap</span><span class="plain"> &amp; </span><span class="constant">ONE_RBIT</span><span class="plain">) </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_bitmap</span><span class="plain"> &amp; </span><span class="constant">VAR_RBIT</span><span class="plain">) </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">ONE_RBIT</span><span class="plain">) </span><span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">VAR_RBIT</span><span class="plain">) </span><span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">FRF_RBIT</span><span class="plain">) </span><span class="identifier">frf</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">frf</span><span class="plain"> &amp;&amp; (</span><span class="identifier">left_unique</span><span class="plain"> != </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">right_unique</span><span class="plain"> != </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_FRFUnavailable</span><span class="plain">),</span>
<span class="string">"fast route-finding is only possible with various-to-various "</span>
<span class="string">"relations"</span><span class="plain">,</span>
<span class="string">"though this doesn't matter because with other relations the "</span>
<span class="string">"standard route-finding algorithm is efficient already."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_3"></a><b>&#167;9.3.3. </b>When a relation is said to hold depending on a condition to be tested at
run-time, it is meaningless to tell Inform anything about the uniqueness of
terms in the domain: a relation might be one-to-one at the start of play
but become various-to-various later on, as the outcomes of these tests
change. So we reject any such misleading syntax.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Detect use of a condition for a test-only relation</span> <span class="cwebmacronumber">9.3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">WHEN_RBIT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_unique</span><span class="plain"> != </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) || (</span><span class="identifier">right_unique</span><span class="plain"> != </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_OneOrVariousWithWhen</span><span class="plain">),</span>
<span class="string">"this relation is a mixture of different syntaxes"</span><span class="plain">,</span>
<span class="string">"and must be simplified. If it is going to specify 'one' or "</span>
<span class="string">"'various' then it cannot also say 'when' the relation holds."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_4"></a><b>&#167;9.3.4. </b>Callings are used to give names to the terms on each side of the relation,
e.g.,
</p>
<blockquote>
<p>Lock-fitting relates one thing (called the matching key) to various things.</p>
</blockquote>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Detect callings for the terms of the relation</span> <span class="cwebmacronumber">9.3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_bitmap</span><span class="plain"> &amp; </span><span class="constant">CALLED_RBIT</span><span class="plain">) || (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">CALLED_RBIT</span><span class="plain">))</span>
<span class="identifier">calling_made</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_5"></a><b>&#167;9.3.5. </b>The second term can be given in several special ways to indicate symmetry
between the two terms. This is more than a declaration that the left and
right terms belong to the same domain set (though that is true): it says
that R(x, y) is true if and only if R(y, x) is true.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Detect use of symmetry in definition of second term</span> <span class="cwebmacronumber">9.3.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">specified_one</span><span class="plain"> = </span><span class="identifier">left_unique</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">ANOTHER_RBIT</span><span class="plain">) {</span>
<span class="identifier">symmetric</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">EACHOTHER_RBIT</span><span class="plain">) {</span>
<span class="identifier">symmetric</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_bitmap</span><span class="plain"> &amp; </span><span class="constant">GROUPS_RBIT</span><span class="plain">) {</span>
<span class="identifier">symmetric</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">left_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">right_unique</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">equivalence</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">specified_one</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">left_unique</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BothOneAndMany</span><span class="plain">),</span>
<span class="string">"the left-hand term in this relation seems to be both 'one' thing "</span>
<span class="string">"and also many things"</span><span class="plain">,</span>
<span class="string">"given the mention of 'each other'. Try removing the 'one'."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_6"></a><b>&#167;9.3.6. </b>To give a name to one term implies some degree of uniqueness about it.
But that only makes sense if there is indeed some uniqueness involved,
because otherwise it is unclear what the name refers to. Who is "the
greeter of the Queen of Sheba" given the following definition?
</p>
<blockquote>
<p>Acquaintance relates various people (called the greeter) to various people.</p>
</blockquote>
<p class="inwebparagraph">Because of that, callings are only allowed in certain circumstances. An
exception is made &mdash; that is, they are always allowed &mdash; where the relation
tests a given condition, because then the names identify the terms, e.g.,
</p>
<blockquote>
<p>Divisibility relates a number (called N) to a number (called M) when the remainder after dividing M by N is 0.</p>
</blockquote>
<p class="inwebparagraph">Here the names "N" and "M" unambiguously refer to the terms being tested
at this moment, and have no currency beyond that context.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Vet the use of callings for the terms of the relation</span> <span class="cwebmacronumber">9.3.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">CONW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_unique</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">LCALLW</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantCallLeft</span><span class="plain">),</span>
<span class="string">"the left-hand term of this relation is not unique"</span><span class="plain">,</span>
<span class="string">"so you cannot assign a name to it using 'called'."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">right_unique</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">RCALLW</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantCallRight</span><span class="plain">),</span>
<span class="string">"the right-hand term of this relation is not unique"</span><span class="plain">,</span>
<span class="string">"so you cannot assign a name to it using 'called'."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">LCALLW</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">RCALLW</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CantCallBoth</span><span class="plain">),</span>
<span class="string">"the terms of the relation can't be named on both sides at once"</span><span class="plain">,</span>
<span class="string">"and because of that it's best to use a single even-handed name: "</span>
<span class="string">"for instance, 'Marriage relates one person to another (called "</span>
<span class="string">"the spouse).' rather than 'Employment relates one person (called "</span>
<span class="string">"the boss) to one person (called the underling).'"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">symmetric</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">left_unique</span><span class="plain">) &amp;&amp; (</span><span class="identifier">right_unique</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">RCALLW</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_OneToOneMiscalled</span><span class="plain">),</span>
<span class="string">"with a one-to-one relation which is not symmetrical "</span>
<span class="string">"only the left-hand item can be given a name using 'called'"</span><span class="plain">,</span>
<span class="string">"so this needs rephrasing to name the left in terms of the right "</span>
<span class="string">"rather than vice versa. For instance, 'Transmission relates "</span>
<span class="string">"one remote to one gadget (called the target).' should be "</span>
<span class="string">"rephrased as 'Transmission relates one gadget (called the "</span>
<span class="string">"target) to one remote.' It will then be possible to talk about "</span>
<span class="string">"'the gadget of' any given remote."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_7"></a><b>&#167;9.3.7. </b>Here we find out the kind which forms the domain on either side. Ideally
we want each to be a fixed-size and fairly small domain set; actually, best
of all is for both kinds to be within "object", since that can be stored
very efficiently, and the worst case is to be forced into "dynamic" storage:
this means using up heap memory allocated dynamically at run-time.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kinds of the terms in the relation</span> <span class="cwebmacronumber">9.3.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Relations::parse_relation_term_type</span><span class="plain">(</span><span class="identifier">FW</span><span class="plain">, &amp;</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="string">"left"</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">symmetric</span><span class="plain">) {</span>
<span class="identifier">right_kind</span><span class="plain"> = </span><span class="identifier">left_kind</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Relations::parse_relation_term_type</span><span class="plain">(</span><span class="identifier">SW</span><span class="plain">, &amp;</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="string">"right"</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">rvno</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))) </span><span class="identifier">rvno</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">CONW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Relations::check_finite_range</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="identifier">dynamic</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">symmetric</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Relations::check_finite_range</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="identifier">dynamic</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_3_8"></a><b>&#167;9.3.8. </b>All forms of relation we can produce from here use an I6 property for
run-time storage (though different forms of relation use it differently).
We use the calling, if any, to name this property: if there are no
callings, then it gets a name like "concealment relation storage", and is
omitted from the index.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Determine property used for run-time storage</span> <span class="cwebmacronumber">9.3.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">LCALLW</span><span class="plain">)) {</span>
<span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::obtain_within_kind</span><span class="plain">(</span><span class="identifier">LCALLW</span><span class="plain">, </span><span class="identifier">left_kind</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">RCALLW</span><span class="plain">)) {</span>
<span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::obtain_within_kind</span><span class="plain">(</span><span class="identifier">RCALLW</span><span class="plain">, </span><span class="identifier">right_kind</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">pw_wa</span><span class="plain"> =</span>
<span class="identifier">Preform::Nonparsing::merge</span><span class="plain">(&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">storage</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">&gt;, 0,</span>
<span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">RW</span><span class="plain">));</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">PW</span><span class="plain"> = </span><span class="identifier">WordAssemblages::to_wording</span><span class="plain">(&amp;</span><span class="identifier">pw_wa</span><span class="plain">);</span>
<span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::obtain_within_kind</span><span class="plain">(</span><span class="identifier">PW</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="functiontext">Properties::exclude_from_index</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">i6_prn_name</span><span class="plain"> = </span><span class="functiontext">Properties::iname</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="identifier">storage_kind</span><span class="plain"> = </span><span class="identifier">left_kind</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">PK</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_unique</span><span class="plain">) {</span>
<span class="identifier">storage_kind</span><span class="plain"> = </span><span class="identifier">right_kind</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_kind</span><span class="plain">) </span><span class="identifier">PK</span><span class="plain"> = </span><span class="identifier">left_kind</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_unique</span><span class="plain">) {</span>
<span class="identifier">storage_kind</span><span class="plain"> = </span><span class="identifier">left_kind</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_kind</span><span class="plain">) </span><span class="identifier">PK</span><span class="plain"> = </span><span class="identifier">right_kind</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">PK</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">PK</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="functiontext">Properties::Valued::set_kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">PK</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">storage_kind</span><span class="plain">) </span><span class="identifier">storage_infs</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">storage_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;storage_kind</span><span class="plain"> = </span><span class="identifier">storage_kind</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">left_unique</span><span class="plain">) || (</span><span class="identifier">right_unique</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">PK</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">PK</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="functiontext">Properties::Valued::now_used_for_non_typesafe_relation</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_3">&#167;9.3</a>.</p>
<p class="inwebparagraph"><a id="SP9_4"></a><b>&#167;9.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message since this won't be stored in a property</span> <span class="cwebmacronumber">9.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelNotStoredInProperty</span><span class="plain">),</span>
<span class="string">"a '(called ...)' name can't be used for this relation"</span><span class="plain">,</span>
<span class="string">"because of the kinds involved in it. (Names for terms in a relation "</span>
<span class="string">"only work if it's possible to store the relation using properties, "</span>
<span class="string">"but that's impossible here, so Inform uses a different scheme.)"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_5"></a><b>&#167;9.5. The completion phase. </b>At this point the BP is filled in except for: its form; the schemas for
testing, asserting true and asserting false; the run-time storage property
to be used, if any; and any fields which are specific to the form in
question. Anyway, there are eight possible forms of explicit BP, so
here are eight paragraphs creating them.
</p>
<p class="inwebparagraph"><a id="SP9_6"></a><b>&#167;9.6. </b>The <code class="display"><span class="extract">Relation_OtoO</span></code> case, or one to one: "R relates one K to one K".
</p>
<p class="inwebparagraph">Such a relation consumes run-time storage of 5D bytes on the Z-machine
and 14D bytes on Glulx, where D is the size of the domain...
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as an asymmetric one-to-one BP</span> <span class="cwebmacronumber">9.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_OtoO</span><span class="plain">;</span>
<span class="identifier">provide_prn</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_Now1to1(*2,%n,*1)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowN1toV(*2,%n,*1)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_Now1to1V(*2,*1,%k,%n)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowN1toVV(*2,*1,%k,%n)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_7"></a><b>&#167;9.7. </b>The <code class="display"><span class="extract">Relation_OtoV</span></code> case, or one to various: "R relates one K to various K".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as a one-to-various BP</span> <span class="cwebmacronumber">9.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_OtoV</span><span class="plain">;</span>
<span class="identifier">provide_prn</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"*2.%n = *1"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowN1toV(*2,%n,*1)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"WriteGProperty(%k, *2, %n, *1)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowN1toVV(*2,*1,%k,%n)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_8"></a><b>&#167;9.8. </b>The <code class="display"><span class="extract">Relation_VtoO</span></code> case, or various to one: "R relates various K to one K".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as a various-to-one BP</span> <span class="cwebmacronumber">9.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_VtoO</span><span class="plain">;</span>
<span class="identifier">provide_prn</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"*1.%n = *2"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowN1toV(*1,%n,*2)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"WriteGProperty(%k, *1, %n, *2)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowN1toVV(*1,*2,%k,%n)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_9"></a><b>&#167;9.9. </b>The <code class="display"><span class="extract">Relation_VtoV</span></code> case, or various to various: "R relates various K to
various K".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as an asymmetric various-to-various BP</span> <span class="cwebmacronumber">9.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_VtoV</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;arbitrary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext">BinaryPredicates::mark_as_needed</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(Relation_TestVtoV(*1,%n,*2,false))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(Relation_NowVtoV(*1,%n,*2,false))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(Relation_NowNVtoV(*1,%n,*2,false))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_10"></a><b>&#167;9.10. </b>The <code class="display"><span class="extract">Relation_Sym_OtoO</span></code> case, or symmetric one to one: "R relates one K to
another".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as a symmetric one-to-one BP</span> <span class="cwebmacronumber">9.10</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">;</span>
<span class="identifier">provide_prn</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowS1to1(*2,%n,*1)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowSN1to1(*2,%n,*1)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowS1to1V(*2,*1,%k,%n)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowSN1to1V(*2,*1,%k,%n)"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_11"></a><b>&#167;9.11. </b>The <code class="display"><span class="extract">Relation_Sym_VtoV</span></code> case, or symmetric various to various: "R relates K
to each other".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as a symmetric various-to-various BP</span> <span class="cwebmacronumber">9.11</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;arbitrary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext">BinaryPredicates::mark_as_needed</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(Relation_TestVtoV(*1,%n,*2,true))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(Relation_NowVtoV(*1,%n,*2,true))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(Relation_NowNVtoV(*1,%n,*2,true))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_12"></a><b>&#167;9.12. </b>The <code class="display"><span class="extract">Relation_Equiv</span></code> case, or equivalence relation: "R relates K to each
other in groups".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as an equivalence-relation BP</span> <span class="cwebmacronumber">9.12</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_Equiv</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;arbitrary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">provide_prn</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(*1.%n == *2.%n)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowEquiv(*1,%n,*2)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowNEquiv(*1,%n,*2)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> =</span>
<span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(GProperty(%k, *1, %n) == GProperty(%k, *2, %n))"</span><span class="plain">,</span>
<span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">, </span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> =</span>
<span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowEquivV(*1,*2,%k,%n)"</span><span class="plain">, </span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> =</span>
<span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"Relation_NowNEquivV(*1,*2,%k,%n)"</span><span class="plain">, </span><span class="identifier">storage_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Properties::Valued::set_kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_13"></a><b>&#167;9.13. </b>The <code class="display"><span class="extract">Relation_ByRoutine</span></code> case, or relation tested by a routine: "R relates
K to L when (some condition)".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete as a relation-by-routine BP</span> <span class="cwebmacronumber">9.13</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="constant">Relation_ByRoutine</span><span class="plain">;</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_by_routine_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">RELATION_FN_HL</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(%n(*1,*2))"</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_by_routine_iname</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;condition_defn_text</span><span class="plain"> = </span><span class="identifier">CONW</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_14"></a><b>&#167;9.14. </b>The left- and right- local variables above provide us with convenient
aliases for the entries which will end up in the <code class="display"><span class="extract">bp_term_details</span></code>
structures attached to the BP: this is where we put them back.
</p>
<p class="inwebparagraph">For the meaning of functions f_0 and f_1, see "Binary Predicates.w".
The idea here is this: suppose we have a relation of objects where the only
true outcomes have the form B(f_0(y), y). At run-time we store the
identity of the counterpart object f_0(y) in the <code class="display"><span class="extract">prn</span></code> property of the
original object y.
</p>
<p class="inwebparagraph">And we similarly construct an f_1 function if the only true outcomes
have the form B(x, f_1(x)).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Add in the reducing functions</span> <span class="cwebmacronumber">9.14</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i6_prn_name</span><span class="plain">) {</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">f0</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">f1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_unique</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_kind</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))</span>
<span class="identifier">f0</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(*1.%n)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">f0</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(GProperty(%k, *1, %n))"</span><span class="plain">,</span>
<span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_unique</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_kind</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))</span>
<span class="identifier">f1</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(*1.%n)"</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">f1</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(GProperty(%k, *1, %n))"</span><span class="plain">,</span>
<span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">i6_prn_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">f0</span><span class="plain">) </span><span class="functiontext">BinaryPredicates::set_term_function</span><span class="plain">(&amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0]), </span><span class="identifier">f0</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">f1</span><span class="plain">) </span><span class="functiontext">BinaryPredicates::set_term_function</span><span class="plain">(&amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1]), </span><span class="identifier">f1</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_15"></a><b>&#167;9.15. </b><code class="display">
&lt;<span class="cwebmacrodefn">Override with dynamic allocation schemata</span> <span class="cwebmacronumber">9.15</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;test_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(RelationTest(%n,RELS_TEST,*1,*2))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_true_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(RelationTest(%n,RELS_ASSERT_TRUE,*1,*2))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;make_false_function</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"(RelationTest(%n,RELS_ASSERT_FALSE,*1,*2))"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Storing relations. </b>At runtime, relation data is sometimes stored in a property, and that needs
to have a name:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">storage</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">&gt; ::=</span>
<span class="plain">... </span><span class="identifier">relation</span><span class="plain"> </span><span class="identifier">storage</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Parsing utilities. </b>A term is specified as a kind.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::parse_relation_term_type</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">set_K</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">side</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) { *</span><span class="identifier">set_K</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="plain">*</span><span class="identifier">set_K</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">side</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelatedKindsUnknown</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the relation definition %1, I am unable to understand the %3-hand "</span>
<span class="string">"side -- I was expecting that %2 would be either the name of a kind, "</span>
<span class="string">"or the name of a kind of value, but it wasn't either of those."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::parse_relation_term_type is used in <a href="#SP9_3_7">&#167;9.3.7</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>A modest utility, to check for a case we forbid because of the prohibitive
(or anyway unpredictable) run-time storage it would imply.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::check_finite_range</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">; </span> <span class="comment">to recover from earlier problems</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) || (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RangeOverlyBroad</span><span class="plain">),</span>
<span class="string">"relations aren't allowed to range over all 'objects' or all 'values'"</span><span class="plain">,</span>
<span class="string">"as these are too broad. A relation has to be between two kinds of "</span>
<span class="string">"object, or kinds of value. So 'Taming relates various people to "</span>
<span class="string">"various animals' is fine, because 'people' and 'animals' both mean "</span>
<span class="string">"kinds of object, but 'Wanting relates various objects to various "</span>
<span class="string">"values' is not allowed."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::check_finite_range is used in <a href="#SP9_3_7">&#167;9.3.7</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Relation records. </b>The template layer needs to be able to perform certain actions on any given
relation, regardless of its mode of storage (if any). We abstract all of this
by giving each relation a "record", which says what it can do, how it does
it, and where it stores its data.
</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>The following permissions are intended to form a bitmap in arbitrary
combinations.
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_SYMMETRIC_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_EQUIVALENCE_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_X_UNIQUE_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_Y_UNIQUE_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_TEST_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_ASSERT_TRUE_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_ASSERT_FALSE_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_SHOW_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_ROUTE_FIND_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_ROUTE_FIND_COUNT_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_LOOKUP_ANY_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_LOOKUP_ALL_X_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_LOOKUP_ALL_Y_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">RELS_LIST_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">REL_BLOCK_HEADER_symbol</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">TTF_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">id</span><span class="plain">, </span><span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">val</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="functiontext">Emit::named_numeric_constant_hex</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_defined_relation_constants</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RELS_SYMMETRIC_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_SYMMETRIC_HL</span><span class="plain">, 0</span><span class="identifier">x8000</span><span class="plain">);</span>
<span class="identifier">RELS_EQUIVALENCE_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_EQUIVALENCE_HL</span><span class="plain">, 0</span><span class="identifier">x4000</span><span class="plain">);</span>
<span class="identifier">RELS_X_UNIQUE_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_X_UNIQUE_HL</span><span class="plain">, 0</span><span class="identifier">x2000</span><span class="plain">);</span>
<span class="identifier">RELS_Y_UNIQUE_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_Y_UNIQUE_HL</span><span class="plain">, 0</span><span class="identifier">x1000</span><span class="plain">);</span>
<span class="identifier">RELS_TEST_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_TEST_HL</span><span class="plain">, 0</span><span class="identifier">x0800</span><span class="plain">);</span>
<span class="identifier">RELS_ASSERT_TRUE_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_ASSERT_TRUE_HL</span><span class="plain">, 0</span><span class="identifier">x0400</span><span class="plain">);</span>
<span class="identifier">RELS_ASSERT_FALSE_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_ASSERT_FALSE_HL</span><span class="plain">, 0</span><span class="identifier">x0200</span><span class="plain">);</span>
<span class="identifier">RELS_SHOW_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_SHOW_HL</span><span class="plain">, 0</span><span class="identifier">x0100</span><span class="plain">);</span>
<span class="identifier">RELS_ROUTE_FIND_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_ROUTE_FIND_HL</span><span class="plain">, 0</span><span class="identifier">x0080</span><span class="plain">);</span>
<span class="identifier">RELS_ROUTE_FIND_COUNT_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_ROUTE_FIND_COUNT_HL</span><span class="plain">, 0</span><span class="identifier">x0040</span><span class="plain">);</span>
<span class="identifier">RELS_LOOKUP_ANY_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ANY_HL</span><span class="plain">, 0</span><span class="identifier">x0008</span><span class="plain">);</span>
<span class="identifier">RELS_LOOKUP_ALL_X_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ALL_X_HL</span><span class="plain">, 0</span><span class="identifier">x0004</span><span class="plain">);</span>
<span class="identifier">RELS_LOOKUP_ALL_Y_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ALL_Y_HL</span><span class="plain">, 0</span><span class="identifier">x0002</span><span class="plain">);</span>
<span class="identifier">RELS_LIST_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">RELS_LIST_HL</span><span class="plain">, 0</span><span class="identifier">x0001</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VirtualMachines::is_16_bit</span><span class="plain">()) {</span>
<span class="identifier">REL_BLOCK_HEADER_symbol</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">REL_BLOCK_HEADER_HL</span><span class="plain">, 0</span><span class="identifier">x100</span><span class="plain">*5 + 13); </span> <span class="comment">2^5 = 32 bytes block</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">REL_BLOCK_HEADER_symbol</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">REL_BLOCK_HEADER_HL</span><span class="plain">, (0</span><span class="identifier">x100</span><span class="plain">*6 + 13)*0</span><span class="identifier">x10000</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">TTF_iname</span><span class="plain"> = </span><span class="functiontext">Relations::compile_defined_relation_constant</span><span class="plain">(</span><span class="constant">TTF_SUM_HL</span><span class="plain">, (0</span><span class="identifier">x0800</span><span class="plain"> + 0</span><span class="identifier">x0400</span><span class="plain"> + 0</span><span class="identifier">x0200</span><span class="plain">));</span>
<span class="comment">i.e., <code class="display"><span class="extract">RELS_TEST + RELS_ASSERT_TRUE + RELS_ASSERT_FALSE</span></code></span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_defined_relation_constant appears nowhere else.</p>
<p class="endnote">The function Relations::compile_defined_relation_constants is used in 1/mr (<a href="1-mr.html#SP4_14">&#167;4.14</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_relation_records</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain">) {</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">minimal</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_equality</span><span class="plain">) || (</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_meaning</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_provision</span><span class="plain">) || (</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_universal</span><span class="plain">))</span>
<span class="identifier">minimal</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;record_needed</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">handler</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;dynamic_memory</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Write the relation handler routine for this BP</span> <span class="cwebmacronumber">15.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the relation record for this BP</span> <span class="cwebmacronumber">15.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">CREATEDYNAMICRELATIONS_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::add_internal_local_c_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"i"</span><span class="plain">, </span><span class="string">"loop counter"</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::add_internal_local_c_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"rel"</span><span class="plain">, </span><span class="string">"new relation"</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;dynamic_memory</span><span class="plain">) &amp;&amp; (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUECREATE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id_as_val</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_NAME_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">, </span><span class="string">"%A"</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain">));</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">A</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">:</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_OTOOADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">:</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_OTOVADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">:</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_VTOOADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">:</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_OTOOADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_SYMMETRICADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Equiv</span><span class="plain">:</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_EQUIVALENCEADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">: </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">:</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_TY_SYMMETRICADJECTIVE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT0V_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;initialiser_iname</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_relation_records is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP15_1"></a><b>&#167;15.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the relation record for this BP</span> <span class="cwebmacronumber">15.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no bp symbol"</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">), </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;dynamic_memory</span><span class="plain">) {</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) 1); </span> <span class="comment">meaning one entry, which is 0; to be filled in later</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Kinds::RunTime::emit_block_value_header</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Write the name field of the relation record</span> <span class="cwebmacronumber">15.1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the permissions field of the relation record</span> <span class="cwebmacronumber">15.1.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the storage field of the relation metadata array</span> <span class="cwebmacronumber">15.1.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the kind field of the relation record</span> <span class="cwebmacronumber">15.1.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the handler field of the relation record</span> <span class="cwebmacronumber">15.1.6</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the description field of the relation record</span> <span class="cwebmacronumber">15.1.5</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP15_1_1"></a><b>&#167;15.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the name field of the relation record</span> <span class="cwebmacronumber">15.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">NF</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">NF</span><span class="plain">, </span><span class="string">"%A relation"</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain">));</span>
<span class="functiontext">Emit::array_text_entry</span><span class="plain">(</span><span class="identifier">NF</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">NF</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1">&#167;15.1</a>.</p>
<p class="inwebparagraph"><a id="SP15_1_2"></a><b>&#167;15.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the permissions field of the relation record</span> <span class="cwebmacronumber">15.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">bm_symb</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">ABILITIES_HL</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_package</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save_sum</span><span class="plain"> = </span><span class="functiontext">Emit::sum_constant_begin</span><span class="plain">(</span><span class="identifier">bm_symb</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">RELS_TEST_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no RELS symbols yet"</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_TEST_iname</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">minimal</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_LOOKUP_ANY_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ALL_X_HL</span><span class="plain">));</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ALL_X_HL</span><span class="plain">));</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_LIST_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Implicit</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">minimal</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">BinaryPredicates::can_be_made_true_at_runtime</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">))) {</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_ASSERT_TRUE_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_ASSERT_FALSE_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_LOOKUP_ANY_iname</span><span class="plain">); </span> <span class="comment">Really?</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">: </span><span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_X_UNIQUE_iname</span><span class="plain">); </span><span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_Y_UNIQUE_iname</span><span class="plain">); </span>&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">: </span><span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_X_UNIQUE_iname</span><span class="plain">); </span>&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">: </span><span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_Y_UNIQUE_iname</span><span class="plain">); </span>&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">:</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_SYMMETRIC_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_X_UNIQUE_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_Y_UNIQUE_iname</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Equiv</span><span class="plain">: </span><span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_EQUIVALENCE_iname</span><span class="plain">); </span>&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">: </span>&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">: </span><span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_SYMMETRIC_iname</span><span class="plain">); </span>&lt;<span class="cwebmacro">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_ByRoutine</span><span class="plain">: </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Binary predicate with unknown structural type"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save_sum</span><span class="plain">); </span> <span class="comment">of the summation, that is</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">bm_symb</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1">&#167;15.1</a>.</p>
<p class="inwebparagraph"><a id="SP15_1_2_1"></a><b>&#167;15.1.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Throw in the full suite</span> <span class="cwebmacronumber">15.1.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_ASSERT_TRUE_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_ASSERT_FALSE_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_SHOW_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">RELS_ROUTE_FIND_iname</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1_2">&#167;15.1.2</a> (7 times).</p>
<p class="inwebparagraph"><a id="SP15_1_3"></a><b>&#167;15.1.3. </b>The storage field has different meanings for different families of BPs:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the storage field of the relation metadata array</span> <span class="cwebmacronumber">15.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Implicit</span><span class="plain">: </span> <span class="comment">Field 0 is not used</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0); </span> <span class="comment">which is not the same as <code class="display"><span class="extract">NULL</span></code>, unlike in C</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Equiv</span><span class="plain">: </span> <span class="comment">Field 0 is the property used for run-time storage</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Properties::iname</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;i6_storage_property</span><span class="plain">));</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">: </span> <span class="comment">Field 0 is the bitmap array used for run-time storage</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;v2v_bitmap_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"gaah"</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;v2v_bitmap_iname</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_ByRoutine</span><span class="plain">: </span> <span class="comment">Field 0 is the routine used to test the relation</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;bp_by_routine_iname</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Binary predicate with unknown structural type"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1">&#167;15.1</a>.</p>
<p class="inwebparagraph"><a id="SP15_1_4"></a><b>&#167;15.1.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the kind field of the relation record</span> <span class="cwebmacronumber">15.1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Kinds::RunTime::emit_strong_id</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1">&#167;15.1</a>.</p>
<p class="inwebparagraph"><a id="SP15_1_5"></a><b>&#167;15.1.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the description field of the relation record</span> <span class="cwebmacronumber">15.1.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">DF</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> == </span><span class="constant">Relation_Implicit</span><span class="plain">)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">DF</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::get_log_name</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">CompiledText::from_text</span><span class="plain">(</span><span class="identifier">DF</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_created_at</span><span class="plain">));</span>
<span class="functiontext">Emit::array_text_entry</span><span class="plain">(</span><span class="identifier">DF</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">DF</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1">&#167;15.1</a>.</p>
<p class="inwebparagraph"><a id="SP15_1_6"></a><b>&#167;15.1.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the handler field of the relation record</span> <span class="cwebmacronumber">15.1.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">handler</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_1">&#167;15.1</a>.</p>
<p class="inwebparagraph"><a id="SP15_2"></a><b>&#167;15.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the relation handler routine for this BP</span> <span class="cwebmacronumber">15.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"X"</span><span class="plain">, *</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"Y"</span><span class="plain">;</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"Y"</span><span class="plain">; </span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"X"</span><span class="plain">; </span><span class="identifier">dbp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">; }</span>
<span class="identifier">handler</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::handler_iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">handler</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">rr_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"rr"</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">task_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"task"</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">X_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Y_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">X_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"X"</span><span class="plain">, &amp;</span><span class="identifier">X_lv</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">Y_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Y"</span><span class="plain">, &amp;</span><span class="identifier">Y_lv</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">Z1_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Z2_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Z3_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Z4_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">Z1_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z1"</span><span class="plain">, </span><span class="string">"loop counter"</span><span class="plain">, &amp;</span><span class="identifier">Z1_lv</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z2"</span><span class="plain">, </span><span class="string">"loop counter"</span><span class="plain">, &amp;</span><span class="identifier">Z2_lv</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">Z3_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z3"</span><span class="plain">, </span><span class="string">"loop counter"</span><span class="plain">, &amp;</span><span class="identifier">Z3_lv</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z4"</span><span class="plain">, </span><span class="string">"loop counter"</span><span class="plain">, &amp;</span><span class="identifier">Z4_lv</span><span class="plain">);</span>
<span class="reserved">annotated_i6_schema</span><span class="plain"> </span><span class="identifier">asch</span><span class="plain">; </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">i6s</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SWITCH_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">task_s</span><span class="plain">);</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_TEST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The TEST task</span> <span class="cwebmacronumber">15.2.4</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">minimal</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">DEFAULT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The default case for minimal relations only</span> <span class="cwebmacronumber">15.2.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ANY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The LOOKUP ANY task</span> <span class="cwebmacronumber">15.2.9</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ALL_X_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The LOOKUP ALL X task</span> <span class="cwebmacronumber">15.2.10</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_LOOKUP_ALL_Y_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The LOOKUP ALL Y task</span> <span class="cwebmacronumber">15.2.11</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_LIST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The LIST task</span> <span class="cwebmacronumber">15.2.12</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">BinaryPredicates::can_be_made_true_at_runtime</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_ASSERT_TRUE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The ASSERT TRUE task</span> <span class="cwebmacronumber">15.2.2</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_ASSERT_FALSE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The ASSERT FALSE task</span> <span class="cwebmacronumber">15.2.3</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">shower</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">par</span><span class="plain"> = 0;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_RSHOWOTOO_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_RSHOWOTOO_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_SHOWOTOO_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_SHOWOTOO_HL</span><span class="plain">); </span><span class="identifier">par</span><span class="plain"> = 1; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Equiv</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_SHOWEQUIV_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_SHOWVTOV_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">: </span><span class="identifier">shower</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_SHOWVTOV_HL</span><span class="plain">); </span><span class="identifier">par</span><span class="plain"> = 1; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shower</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_SHOW_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The SHOW task</span> <span class="cwebmacronumber">15.2.7</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">emptier</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">par</span><span class="plain"> = 0;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYOTOO_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYOTOO_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYOTOO_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYOTOO_HL</span><span class="plain">); </span><span class="identifier">par</span><span class="plain"> = 1; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Equiv</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYEQUIV_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYVTOV_HL</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">: </span><span class="identifier">emptier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATION_EMPTYVTOV_HL</span><span class="plain">); </span><span class="identifier">par</span><span class="plain"> = 1; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">emptier</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_EMPTY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The EMPTY task</span> <span class="cwebmacronumber">15.2.8</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">router</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">id_flag</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">follow</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">: </span><span class="identifier">router</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">OTOVRELROUTETO_HL</span><span class="plain">); </span><span class="identifier">follow</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">: </span><span class="identifier">router</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">OTOVRELROUTETO_HL</span><span class="plain">); </span><span class="identifier">follow</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">: </span><span class="identifier">router</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">VTOORELROUTETO_HL</span><span class="plain">); </span><span class="identifier">follow</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">:</span>
<span class="identifier">id_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">router</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">VTOVRELROUTETO_HL</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">router</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_ROUTE_FIND_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The ROUTE FIND task</span> <span class="cwebmacronumber">15.2.5</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_ROUTE_FIND_COUNT_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">The ROUTE FIND COUNT task</span> <span class="cwebmacronumber">15.2.6</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_1"></a><b>&#167;15.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">The default case for minimal relations only</span> <span class="cwebmacronumber">15.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RUNTIMEPROBLEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RTP_RELMINIMAL_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">task_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_2"></a><b>&#167;15.2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">The ASSERT TRUE task</span> <span class="cwebmacronumber">15.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">asch</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::Compile::blank_asch</span><span class="plain">();</span>
<span class="identifier">i6s</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_i6_schema</span><span class="plain">(</span><span class="constant">NOW_ATOM_TRUE_TASK</span><span class="plain">, </span><span class="identifier">dbp</span><span class="plain">, &amp;</span><span class="identifier">asch</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i6s</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(</span><span class="identifier">i6s</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">, </span><span class="identifier">Y_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_3"></a><b>&#167;15.2.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">The ASSERT FALSE task</span> <span class="cwebmacronumber">15.2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">asch</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::Compile::blank_asch</span><span class="plain">();</span>
<span class="identifier">i6s</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_i6_schema</span><span class="plain">(</span><span class="constant">NOW_ATOM_FALSE_TASK</span><span class="plain">, </span><span class="identifier">dbp</span><span class="plain">, &amp;</span><span class="identifier">asch</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i6s</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(</span><span class="identifier">i6s</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">, </span><span class="identifier">Y_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_4"></a><b>&#167;15.2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">The TEST task</span> <span class="cwebmacronumber">15.2.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">asch</span><span class="plain"> = </span><span class="functiontext">Calculus::Atoms::Compile::blank_asch</span><span class="plain">();</span>
<span class="identifier">i6s</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_i6_schema</span><span class="plain">(</span><span class="constant">TEST_ATOM_TASK</span><span class="plain">, </span><span class="identifier">dbp</span><span class="plain">, &amp;</span><span class="identifier">asch</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">adapted</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;2; </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">fnsc</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_term_as_function_of_other</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fnsc</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> == 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="functiontext">Calculus::Schemas::emit_val_expand_from_locals</span><span class="plain">(</span><span class="identifier">fnsc</span><span class="plain">, </span><span class="identifier">Y_lv</span><span class="plain">, </span><span class="identifier">Y_lv</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">adapted</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="functiontext">Calculus::Schemas::emit_val_expand_from_locals</span><span class="plain">(</span><span class="identifier">fnsc</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">adapted</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">adapted</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i6s</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Calculus::Schemas::emit_val_expand_from_locals</span><span class="plain">(</span><span class="identifier">i6s</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">, </span><span class="identifier">Y_lv</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_5"></a><b>&#167;15.2.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">The ROUTE FIND task</span> <span class="cwebmacronumber">15.2.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT3_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">router</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Expand the ID operand</span> <span class="cwebmacronumber">15.2.5.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_5_1"></a><b>&#167;15.2.5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Expand the ID operand</span> <span class="cwebmacronumber">15.2.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">id_flag</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLNGETF_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RR_STORAGE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2_5">&#167;15.2.5</a>, <a href="#SP15_2_6">&#167;15.2.6</a> (twice).</p>
<p class="inwebparagraph"><a id="SP15_2_6"></a><b>&#167;15.2.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">The ROUTE FIND COUNT task</span> <span class="cwebmacronumber">15.2.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">follow</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELFOLLOWVECTOR_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT3_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">router</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Expand the ID operand</span> <span class="cwebmacronumber">15.2.5.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT4_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">router</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Expand the ID operand</span> <span class="cwebmacronumber">15.2.5.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_7"></a><b>&#167;15.2.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">The SHOW task</span> <span class="cwebmacronumber">15.2.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT2V_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">shower</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">par</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_8"></a><b>&#167;15.2.8. </b><code class="display">
&lt;<span class="cwebmacrodefn">The EMPTY task</span> <span class="cwebmacronumber">15.2.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT3_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">emptier</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">par</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_9"></a><b>&#167;15.2.9. </b><code class="display">
&lt;<span class="cwebmacrodefn">The LOOKUP ANY task</span> <span class="cwebmacronumber">15.2.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OR_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLANY_GET_X_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLANY_CAN_GET_X_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Write rels lookup</span> <span class="cwebmacronumber">15.2.9.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">t</span><span class="plain"> = 1;</span>
&lt;<span class="cwebmacro">Write rels lookup</span> <span class="cwebmacronumber">15.2.9.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_10"></a><b>&#167;15.2.10. </b><code class="display">
&lt;<span class="cwebmacrodefn">The LOOKUP ALL X task</span> <span class="cwebmacronumber">15.2.10</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_SETLENGTH_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Write rels lookup list</span> <span class="cwebmacronumber">15.2.10.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_11"></a><b>&#167;15.2.11. </b><code class="display">
&lt;<span class="cwebmacrodefn">The LOOKUP ALL Y task</span> <span class="cwebmacronumber">15.2.11</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_SETLENGTH_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = 1;</span>
&lt;<span class="cwebmacro">Write rels lookup list</span> <span class="cwebmacronumber">15.2.10.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_12"></a><b>&#167;15.2.12. </b><code class="display">
&lt;<span class="cwebmacrodefn">The LIST task</span> <span class="cwebmacronumber">15.2.12</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_SETLENGTH_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLIST_ALL_X_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Write rels lookup list all</span> <span class="cwebmacronumber">15.2.12.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLIST_ALL_Y_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">t</span><span class="plain"> = 1;</span>
&lt;<span class="cwebmacro">Write rels lookup list all</span> <span class="cwebmacronumber">15.2.12.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2">&#167;15.2</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_9_1"></a><b>&#167;15.2.9.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write rels lookup</span> <span class="cwebmacronumber">15.2.9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_containment</span><span class="plain">) &amp;&amp; (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::compile_domain_possible</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="reserved">i6_schema</span><span class="plain"> </span><span class="identifier">loop_schema</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::write_loop_schema</span><span class="plain">(&amp;</span><span class="identifier">loop_schema</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(&amp;</span><span class="identifier">loop_schema</span><span class="plain">, </span><span class="identifier">Z1_lv</span><span class="plain">, </span><span class="identifier">Z2_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT4_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::handler_iname</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_TEST_HL</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == 0) {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLANY_CAN_GET_X_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLANY_CAN_GET_Y_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLANY_CAN_GET_X_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RLANY_CAN_GET_Y_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEFAULTVALUEOFKOV_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2_9">&#167;15.2.9</a> (twice).</p>
<p class="inwebparagraph"><a id="SP15_2_10_1"></a><b>&#167;15.2.10.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write rels lookup list</span> <span class="cwebmacronumber">15.2.10.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_containment</span><span class="plain">) &amp;&amp; (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::compile_domain_possible</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="reserved">i6_schema</span><span class="plain"> </span><span class="identifier">loop_schema</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::write_loop_schema</span><span class="plain">(&amp;</span><span class="identifier">loop_schema</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(&amp;</span><span class="identifier">loop_schema</span><span class="plain">, </span><span class="identifier">Z1_lv</span><span class="plain">, </span><span class="identifier">Z2_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT4_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::handler_iname</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_TEST_HL</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == 0) {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_INSERTITEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Y_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2_10">&#167;15.2.10</a>, <a href="#SP15_2_11">&#167;15.2.11</a>.</p>
<p class="inwebparagraph"><a id="SP15_2_12_1"></a><b>&#167;15.2.12.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write rels lookup list all</span> <span class="cwebmacronumber">15.2.12.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KL</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">, 0);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KR</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">, 1);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_containment</span><span class="plain">) &amp;&amp; (</span><span class="identifier">KL</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">KL</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dbp</span><span class="plain"> == </span><span class="identifier">R_containment</span><span class="plain">) &amp;&amp; (</span><span class="identifier">KR</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">KR</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Behaviour::compile_domain_possible</span><span class="plain">(</span><span class="identifier">KL</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Kinds::Behaviour::compile_domain_possible</span><span class="plain">(</span><span class="identifier">KL</span><span class="plain">))) {</span>
<span class="reserved">i6_schema</span><span class="plain"> </span><span class="identifier">loop_schema_L</span><span class="plain">, </span><span class="identifier">loop_schema_R</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Calculus::Deferrals::write_loop_schema</span><span class="plain">(&amp;</span><span class="identifier">loop_schema_L</span><span class="plain">, </span><span class="identifier">KL</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Calculus::Deferrals::write_loop_schema</span><span class="plain">(&amp;</span><span class="identifier">loop_schema_R</span><span class="plain">, </span><span class="identifier">KR</span><span class="plain">))) {</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(&amp;</span><span class="identifier">loop_schema_L</span><span class="plain">, </span><span class="identifier">Z1_lv</span><span class="plain">, </span><span class="identifier">Z2_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(&amp;</span><span class="identifier">loop_schema_R</span><span class="plain">, </span><span class="identifier">Z3_lv</span><span class="plain">, </span><span class="identifier">Z4_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT4_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::handler_iname</span><span class="plain">(</span><span class="identifier">dbp</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rr_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELS_TEST_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z3_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_INSERTITEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == 0) {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z1_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Z3_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15_2_12">&#167;15.2.12</a> (twice).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>And now a variation for default values: for example, an anonymous relation
between numbers and texts.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_default_relation</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::emit_block_value_header</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">, </span><span class="string">"default value of "</span><span class="plain">); </span><span class="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="functiontext">Emit::array_text_entry</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">TTF_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">EMPTYRELATIONHANDLER_HL</span><span class="plain">));</span>
<span class="functiontext">Emit::array_text_entry</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_blank_relation</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="functiontext">Kinds::RunTime::emit_block_value_header</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 34);</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">, </span><span class="string">"anonymous "</span><span class="plain">); </span><span class="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="functiontext">Emit::array_text_entry</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">DVT</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">TTF_iname</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(7);</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">EK</span><span class="plain"> = </span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">EK</span><span class="plain">))</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">HASHLISTRELATIONHANDLER_HL</span><span class="plain">));</span>
<span class="reserved">else</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DOUBLEHASHSETRELATIONHANDLER_HL</span><span class="plain">));</span>
<span class="functiontext">Emit::array_text_entry</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"an anonymous relation"</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;24; </span><span class="identifier">i</span><span class="plain">++) </span><span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_default_relation is used in 13/rsfk (<a href="13-rsfk.html#SP16_2">&#167;16.2</a>).</p>
<p class="endnote">The function Relations::compile_blank_relation is used in 13/rsfk (<a href="13-rsfk.html#SP4">&#167;4</a>).</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Support for the RELATIONS command. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::IterateRelations</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">ITERATERELATIONS_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">callback_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"callback"</span><span class="plain">);</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;record_needed</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT1V_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">callback_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::IterateRelations is used in 1/mr (<a href="1-mr.html#SP4_14">&#167;4.14</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. The bitmap for various-to-various relations. </b>It is unavoidable that a general V-to-V relation will take at least LR bits
of storage, where L is the size of the left domain and R the size of the
right domain. (A symmetric V-to-V relation needs only a little over LR/2 bits,
though in practice we don't want the nuisance of this memory saving.) Cheaper
implementations would only be possible if we could guarantee that the relation
would have some regularity, or would be sparse, but we can't guarantee any
of that. Our strategy will therefore be to store these LR bits in the most
direct way possible, with as little overhead as possible: in a bitmap.
</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>The following code compiles a stream of bits into a sequence of 16-bit
I6 constants written in hexadecimal, padding out with 0s to fill any incomplete
word left at the end. The first bit of the stream becomes the least significant
bit of the first word of the output.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">word_compiled</span><span class="plain"> = 0, </span><span class="identifier">bit_counter</span><span class="plain"> = 0, </span><span class="identifier">words_compiled</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::begin_bit_stream</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">word_compiled</span><span class="plain"> = 0; </span><span class="identifier">bit_counter</span><span class="plain"> = 0; </span><span class="identifier">words_compiled</span><span class="plain"> = 0;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_bit</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">b</span><span class="plain">) {</span>
<span class="identifier">word_compiled</span><span class="plain"> += (</span><span class="identifier">b</span><span class="plain"> &lt;&lt; </span><span class="identifier">bit_counter</span><span class="plain">);</span>
<span class="identifier">bit_counter</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bit_counter</span><span class="plain"> == 16) {</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">word_compiled</span><span class="plain">);</span>
<span class="identifier">words_compiled</span><span class="plain">++;</span>
<span class="identifier">word_compiled</span><span class="plain"> = 0; </span><span class="identifier">bit_counter</span><span class="plain"> = 0;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::end_bit_stream</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">bit_counter</span><span class="plain"> != 0) </span><span class="functiontext">Relations::compile_bit</span><span class="plain">(0);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::begin_bit_stream is used in <a href="#SP20_5">&#167;20.5</a>.</p>
<p class="endnote">The function Relations::compile_bit is used in <a href="#SP20_5">&#167;20.5</a>.</p>
<p class="endnote">The function Relations::end_bit_stream is used in <a href="#SP20_5">&#167;20.5</a>.</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>As was implied above, the run-time storage for a various to various relation
whose BP has allocation ID number <code class="display"><span class="extract">X</span></code> is an I6 word array called <code class="display"><span class="extract">V2V_Bitmap_X</span></code>.
This begins with a header of 8 words and is then followed by a bitmap.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_vtov_storage</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">left_count</span><span class="plain"> = 0, </span><span class="identifier">right_count</span><span class="plain"> = 0, </span><span class="identifier">words_used</span><span class="plain"> = 0, </span><span class="identifier">bytes_used</span><span class="plain"> = 0;</span>
<span class="functiontext">Relations::allocate_index_storage</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Index the left and right domains and calculate their sizes</span> <span class="cwebmacronumber">20.1</span>&gt;<span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">v2v_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_count</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">right_count</span><span class="plain"> &gt; 0))</span>
&lt;<span class="cwebmacro">Allocate a zeroed-out memory cache for relations with fast route-finding</span> <span class="cwebmacronumber">20.3</span>&gt;<span class="plain">;</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;v2v_bitmap_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">BITMAP_HL</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;v2v_bitmap_iname</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Compile header information in the V-to-V structure</span> <span class="cwebmacronumber">20.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_count</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">right_count</span><span class="plain"> &gt; 0))</span>
&lt;<span class="cwebmacro">Compile bitmap pre-initialised to the V-to-V relation at start of play</span> <span class="cwebmacronumber">20.5</span>&gt;<span class="plain">;</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">rname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rname</span><span class="plain">, </span><span class="string">"%A"</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain">));</span>
<span class="functiontext">VirtualMachines::note_usage</span><span class="plain">(</span><span class="string">"relation"</span><span class="plain">,</span>
<span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_created_at</span><span class="plain">), </span><span class="identifier">rname</span><span class="plain">, </span><span class="identifier">words_used</span><span class="plain">, </span><span class="identifier">bytes_used</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">rname</span><span class="plain">);</span>
<span class="functiontext">Relations::free_index_storage</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_vtov_storage is used in 6/bp (<a href="6-bp.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP20_1"></a><b>&#167;20.1. </b>We calculate numbers L and R, and index the items being related, so that
the possible left values are indexed 0, 1, 2, ..., L-1 and the possible
right values 0, 1, 2, ..., R-1. Note that in a relation such as
</p>
<blockquote>
<p>Roominess relates various things to various containers.</p>
</blockquote>
<p class="inwebparagraph">the same object (if a container) might be in both the left and right domains,
and be indexed differently on each side: it might be thing number 11 but
container number 6, for instance.
</p>
<p class="inwebparagraph">L and R are stored in the variables <code class="display"><span class="extract">left_count</span></code> and <code class="display"><span class="extract">right_count</span></code>. If
the left domain contains objects, the index of a member <code class="display"><span class="extract">I</span></code> is stored in
RI 0; if the right domain does, then in RI 1. If the domain set is an
enumerated kind of value, no index needs to be stored, because the values
are already enumerated 1, 2, 3, ..., N for some N. The actual work in
this is done by the routine <code class="display"><span class="extract">Relations::relation_range</span></code> (below).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Index the left and right domains and calculate their sizes</span> <span class="cwebmacronumber">20.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">left_count</span><span class="plain"> = </span><span class="functiontext">Relations::relation_range</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 0);</span>
<span class="identifier">right_count</span><span class="plain"> = </span><span class="functiontext">Relations::relation_range</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 1);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP20_2"></a><b>&#167;20.2. </b>See "Relations.i6t" in the template layer for details.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile header information in the V-to-V structure</span> <span class="cwebmacronumber">20.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">left_kind</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 0);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">right_kind</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 1);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">left_count</span><span class="plain"> &gt; 0)) {</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">PL::Counting::instance_count_property_symbol</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">right_count</span><span class="plain"> &gt; 0)) {</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">PL::Counting::instance_count_property_symbol</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">left_count</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">right_count</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">));</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">));</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(1); </span> <span class="comment">Cache broken flag</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_count</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">right_count</span><span class="plain"> &gt; 0))</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">v2v_iname</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="identifier">words_used</span><span class="plain"> += 8;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP20_3"></a><b>&#167;20.3. </b>Fast route finding is available only where the left and right domains are
equal, and even then, only when the user asked for it. If so, we allocate
LR bytes as a cache if L=R&lt;256, and LR words otherwise. The cache
is initialised to all-zeros, which saves an inordinate amount of nuisance,
and this is why the "cache broken" flag is initially set in the header
above: it forces the template layer to generate the cache when first used.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Allocate a zeroed-out memory cache for relations with fast route-finding</span> <span class="cwebmacronumber">20.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::package</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">ROUTE_CACHE_HL</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">left_kind</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 0);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">right_kind</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 1);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;fast_route_finding</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">right_kind</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">left_kind</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">left_count</span><span class="plain"> == </span><span class="identifier">right_count</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_count</span><span class="plain"> &lt; 256) {</span>
<span class="identifier">v2v_iname</span><span class="plain"> = </span><span class="identifier">iname</span><span class="plain">;</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_byte_array_begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) (2*</span><span class="identifier">left_count</span><span class="plain">*</span><span class="identifier">left_count</span><span class="plain">));</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="identifier">bytes_used</span><span class="plain"> += 2*</span><span class="identifier">left_count</span><span class="plain">*</span><span class="identifier">left_count</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">v2v_iname</span><span class="plain"> = </span><span class="identifier">iname</span><span class="plain">;</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) (2*</span><span class="identifier">left_count</span><span class="plain">*</span><span class="identifier">left_count</span><span class="plain">));</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="identifier">words_used</span><span class="plain"> += 2*</span><span class="identifier">left_count</span><span class="plain">*</span><span class="identifier">left_count</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">v2v_iname</span><span class="plain"> = </span><span class="functiontext">Emit::named_numeric_constant</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, 0);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP20_4"></a><b>&#167;20.4. </b>The following routine conveniently determines whether a given INFS is
within the domain of one of the terms of a relation; the rule is that it
mustn't itself express a domain (otherwise, e.g., the kind "woman" would
show up as within the domain of "person" &mdash; we want only instances here,
not kinds); and that it must inherit from the domain of the term.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::infs_in_domain</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">index</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">) != </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">domain_infs</span><span class="plain"> = </span><span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">InferenceSubjects::is_strictly_within</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">domain_infs</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::infs_in_domain is used in <a href="#SP20_5">&#167;20.5</a>, <a href="#SP21">&#167;21</a>.</p>
<p class="inwebparagraph"><a id="SP20_5"></a><b>&#167;20.5. </b>Now to assemble the bitmap. We do this by looking at inferences in the world-model
to find out what pairs (x, y) are such that assertions have declared that
B(x, y) is true.
</p>
<p class="inwebparagraph">It would be convenient if the inferences could feed us the necessary
information in exactly the right order, but life is not that kind. On the
other hand it would be quicker and easier if we built the entire bitmap in
memory, so that it could send the pairs (x, y) in any order at all, but
that's a little wasteful. We compromise and build the bitmap one row at a
time, requiring us to store a whole row, but allowing the world-model code
to send the pairs in that row in any order.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile bitmap pre-initialised to the V-to-V relation at start of play</span> <span class="cwebmacronumber">20.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">row_flags</span><span class="plain"> = </span><span class="identifier">Memory::I7_malloc</span><span class="plain">(</span><span class="identifier">right_count</span><span class="plain">, </span><span class="constant">RELATION_CONSTRUCTION_MREASON</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">row_flags</span><span class="plain">) {</span>
<span class="functiontext">Relations::begin_bit_stream</span><span class="plain">();</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Relations::infs_in_domain</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, 0)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">right_count</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) </span><span class="identifier">row_flags</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = 0;</span>
&lt;<span class="cwebmacro">Find all pairs belonging to this row, and set the relevant flags</span> <span class="cwebmacronumber">20.5.1</span>&gt;<span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">right_count</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) </span><span class="functiontext">Relations::compile_bit</span><span class="plain">(</span><span class="identifier">row_flags</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]);</span>
<span class="plain">}</span>
<span class="functiontext">Relations::end_bit_stream</span><span class="plain">();</span>
<span class="identifier">words_used</span><span class="plain"> += </span><span class="identifier">words_compiled</span><span class="plain">;</span>
<span class="identifier">Memory::I7_free</span><span class="plain">(</span><span class="identifier">row_flags</span><span class="plain">, </span><span class="constant">RELATION_CONSTRUCTION_MREASON</span><span class="plain">, </span><span class="identifier">right_count</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP20_5_1"></a><b>&#167;20.5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Find all pairs belonging to this row, and set the relevant flags</span> <span class="cwebmacronumber">20.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::as_subject</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">), </span><span class="constant">ARBITRARY_RELATION_INF</span><span class="plain">) {</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">left_infs</span><span class="plain">, *</span><span class="identifier">right_infs</span><span class="plain">;</span>
<span class="functiontext">World::Inferences::get_references</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, &amp;</span><span class="identifier">left_infs</span><span class="plain">, &amp;</span><span class="identifier">right_infs</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infs</span><span class="plain"> == </span><span class="identifier">left_infs</span><span class="plain">) </span><span class="identifier">row_flags</span><span class="plain">[</span><span class="functiontext">Relations::get_relation_index</span><span class="plain">(</span><span class="identifier">right_infs</span><span class="plain">, 1)] = 1;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20_5">&#167;20.5</a>.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>Lastly on this: the way we count and index the left (<code class="display"><span class="extract">index=0</span></code>) or right (1)
domain. We count upwards from 0 (in order of creation).
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::relation_range</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">index</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = 0;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Relations::infs_in_domain</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">)) </span><span class="functiontext">Relations::set_relation_index</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">++);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Relations::set_relation_index</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">, -1);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::relation_range is used in <a href="#SP20_1">&#167;20.1</a>.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>Tiresomely, we have to store these indices for a little while, so:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">relation_indices</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::allocate_index_storage</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nc</span><span class="plain"> = </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain">);</span>
<span class="identifier">relation_indices</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain"> *) (</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, 2*</span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::set_relation_index</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">relation_indices</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"relation index unallocated"</span><span class="plain">);</span>
<span class="identifier">relation_indices</span><span class="plain">[2*(</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">) + </span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">v</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::get_relation_index</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">relation_indices</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"relation index unallocated"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">relation_indices</span><span class="plain">[2*(</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">) + </span><span class="identifier">i</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::free_index_storage</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">relation_indices</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"relation index unallocated"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nc</span><span class="plain"> = </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain">);</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">relation_indices</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, 2*</span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">));</span>
<span class="identifier">relation_indices</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::allocate_index_storage is used in <a href="#SP20">&#167;20</a>.</p>
<p class="endnote">The function Relations::set_relation_index is used in <a href="#SP21">&#167;21</a>.</p>
<p class="endnote">The function Relations::get_relation_index is used in <a href="#SP20_5_1">&#167;20.5.1</a>.</p>
<p class="endnote">The function Relations::free_index_storage is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. The partition for an equivalence relation. </b>An equivalence relation E is such that E(x, x) for all x, such that
E(x, y) if and only if E(y, x), and such that E(x, y) and E(y, z)
together imply E(x, z): the properties of being reflexive, symmetric
and transitive. The relation constructed by a sentence like
</p>
<blockquote>
<p>Alliance relates people to each other in groups.</p>
</blockquote>
<p class="inwebparagraph">is to be an equivalence relation. This means we need to ensure first that
the original state of the relation, resulting from assertions such as...
</p>
<blockquote>
<p>The verb to be allied to implies the alliance relation. Louis is allied to Otto. Otto is allied to Helene.</p>
</blockquote>
<p class="inwebparagraph">...satisfies the reflexive, symmetric and transitive properties; and then
also that these properties are maintained at run-time when the situation
changes as a result of executing phrases such as
</p>
<blockquote>
<p>now Louis is allied to Gustav;</p>
</blockquote>
<p class="inwebparagraph">We use the same solution both in the compiler and at run-time, which is to
exploit an elementary theorem about ERs. Let E be an equivalence relation
on the members of a set S (say, the set of people in Central Europe).
Then there is a unique way to divide up S into a "partition" of subsets
called "equivalence classes" such that:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) every member of S is in exactly one of the classes,
</li><li>(b) none of the classes is empty, and
</li><li>(c) E(x, y) is true if and only if x and y belong to the same class.
</li></ul>
<p class="inwebparagraph">Conversely, given any partition of S (i.e., satisfying (a) and (b)),
there is a unique equivalence relation E such that (c) is true. In short:
possible states of an equivalence relation on a set correspond exactly to
possible ways to divide it up into non-empty, non-overlapping pieces.
</p>
<p class="inwebparagraph">We therefore store the current state not as some list of which pairs (x, y)
for which E(x, y) is true, but instead as a partition of the set S. We
store this as a function p:S--&gt; { 1, 2, 3, ...} such
that x and y belong in the same class &mdash; or to put it another way, such
that E(x, y) is true &mdash; if and only if p(x) = p(y). When we are assembling
the initial state, the function p is an array of integers whose address is
stored in the <code class="display"><span class="extract">bp-&gt;equivalence_partition</span></code> field of the BP structure. It is
then compiled into the storage properties of the I6 objects concerned. For
instance, if we have <code class="display"><span class="extract">p44_alliance</span></code> as the storage property for the "alliance"
relation, then <code class="display"><span class="extract">O31_Louis.p44_alliance</span></code> and <code class="display"><span class="extract">O32_Otto.p44_alliance</span></code> will be
set to the same partition number. The template routines which set and remove
alliance then maintain the collective values of the <code class="display"><span class="extract">p44_alliance</span></code> property,
keeping it always a valid partition function for the relation.
</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>We calculate the initial partition by starting with the sparsest possible
equivalence relation, E(x, y) if and only if x=y, where each member is
related only to itself. (This is the equality relation.) The partition
function here is given by p(x) equals the allocation ID number for object
x, plus 1. Since all objects have distinct IDs, p(x)=p(y) if and only
if x=y, which is what we want. But note that the objects in S may well
not have contiguous ID numbers. This doesn't matter to us, but it means p
may look less tidy than we expect.
</p>
<p class="inwebparagraph">For instance, suppose there are five people: Sophie, Ryan, Daisy, Owen and
the player, with a "helping" equivalence relation. We might then generate
the initial partition:
p(P) = 12, p(S) = 23, p(R) = 25, p(D) = 26, p(O) = 31.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::equivalence_relation_make_singleton_partitions</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">domain_size</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">partition_array</span><span class="plain"> = </span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">domain_size</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">), </span><span class="constant">PARTITION_MREASON</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">domain_size</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">partition_array</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">i</span><span class="plain">+1;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;equivalence_partition</span><span class="plain"> = </span><span class="identifier">partition_array</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::equivalence_relation_make_singleton_partitions is used in 6/bp (<a href="6-bp.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>The A-parser has meanwhile been reading in facts about the helping relation:
</p>
<blockquote>
<p>Sophie helps Ryan. Daisy helps Ryan. Owen helps the player.</p>
</blockquote>
<p class="inwebparagraph">And it feeds these facts to us one at a time. It tells us that A(S, R)
has to be true by calling the routine below for the helping relation with
the ID numbers of Sophie and Ryan as arguments. Sophie is currently in
class number 23, Ryan in class 25. We merge these two classes so that
anybody whose class number is 25 is moved down to have class number 23, and
so:
p(P) = 12, p(S) = 23, p(R) = 23, p(D) = 26, p(O) = 31.
Similarly we now merge Daisy's class with Ryan's:
p(P) = 12, p(S) = 23, p(R) = 23, p(D) = 23, p(O) = 31.
And Owen's with the player's:
p(P) = 12, p(S) = 23, p(R) = 23, p(D) = 23, p(O) = 12.
This leaves us with the final partition where the two equivalence classes are
{ player, Owen } { Sophie,
Daisy, Ryan}.
As mentioned above, it might seem "tidy" to renumber these classes 1 and 2
rather than 12 and 23, but there's really no need and we don't bother.
</p>
<p class="inwebparagraph">Note that the A-parser does not allow negative assertions about equivalence
relations to be made:
</p>
<blockquote>
<p>Daisy does not help Ryan.</p>
</blockquote>
<p class="inwebparagraph">While we could try to accommodate this (using the same method we use at
run-time to handle "now Daisy does not help Ryan"), it would only invite
users to set up these relations in a stylistically poor way.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::equivalence_relation_merge_classes</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">domain_size</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ix1</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ix2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> != </span><span class="constant">Relation_Equiv</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"attempt to merge classes for a non-equivalence relation"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">partition_array</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;equivalence_partition</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">partition_array</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"attempt to use null equivalence partition array"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">little</span><span class="plain">, </span><span class="identifier">big</span><span class="plain">; </span> <span class="comment">or, The Fairies' Parliament</span>
<span class="identifier">big</span><span class="plain"> = </span><span class="identifier">partition_array</span><span class="plain">[</span><span class="identifier">ix1</span><span class="plain">]; </span><span class="identifier">little</span><span class="plain"> = </span><span class="identifier">partition_array</span><span class="plain">[</span><span class="identifier">ix2</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">big</span><span class="plain"> == </span><span class="identifier">little</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">big</span><span class="plain"> &lt; </span><span class="identifier">little</span><span class="plain">) { </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">swap</span><span class="plain"> = </span><span class="identifier">little</span><span class="plain">; </span><span class="identifier">little</span><span class="plain"> = </span><span class="identifier">big</span><span class="plain">; </span><span class="identifier">big</span><span class="plain"> = </span><span class="identifier">swap</span><span class="plain">; }</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">domain_size</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">partition_array</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="identifier">big</span><span class="plain">)</span>
<span class="identifier">partition_array</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">little</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::equivalence_relation_merge_classes is used in 6/bp (<a href="6-bp.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b>Once that process has completed, the code which compiles the
initial state of the I6 object tree calls the following routine to ask it
to fill in the (let's say) <code class="display"><span class="extract">p63_helping</span></code> property for each person
in turn.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::equivalence_relation_add_properties</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::term_kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, 1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">) {</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Set the partition number property</span> <span class="cwebmacronumber">26.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">nc</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_INSTANCES</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">) {</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Set the partition number property</span> <span class="cwebmacronumber">26.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::equivalence_relation_add_properties is used in 6/bp (<a href="6-bp.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP26_1"></a><b>&#167;26.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Set the partition number property</span> <span class="cwebmacronumber">26.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_int</span><span class="plain">(</span>
<span class="functiontext">Relations::equivalence_relation_get_class</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">), </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="functiontext">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;i6_storage_property</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP26">&#167;26</a> (twice).</p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. </b>Where:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Relations::equivalence_relation_get_class</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ix</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> != </span><span class="constant">Relation_Equiv</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"attempt to merge classes for a non-equivalence relation"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">partition_array</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;equivalence_partition</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">partition_array</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"attempt to use null equivalence partition array"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">partition_array</span><span class="plain">[</span><span class="identifier">ix</span><span class="plain">];</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::equivalence_relation_get_class is used in <a href="#SP26_1">&#167;26.1</a>.</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Checking correctness of 1-to-1 relations. </b>We now check 1-to-1 relations to see if the initial conditions have
violated the 1-to-1-ness. Because of the way these relations are implemented
using a property, it seems in fact to be impossible to violate the left-hand
count &mdash; a contradiction problem is reported when the inference was generated.
But in case the implementation is ever changed, it seems prudent to leave this
checking in.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::check_OtoO_relation</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nc</span><span class="plain"> = </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">right_counts</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain"> *)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference</span><span class="plain"> **</span><span class="identifier">right_first</span><span class="plain"> = (</span><span class="reserved">inference</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference</span><span class="plain"> **</span><span class="identifier">right_second</span><span class="plain"> = (</span><span class="reserved">inference</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::get_i6_storage_property</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) </span><span class="identifier">right_counts</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] = 0;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) {</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">leftc</span><span class="plain"> = 0;</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
<span class="identifier">KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="constant">PROPERTY_INF</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">prn</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">World::Inferences::get_certainty</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">CERTAIN_CE</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="functiontext">World::Inferences::get_property_value</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs2</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::from_specification</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
<span class="identifier">leftc</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infs2</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> = </span><span class="identifier">right_counts</span><span class="plain">[</span><span class="identifier">infs2</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == 0) </span><span class="identifier">right_first</span><span class="plain">[</span><span class="identifier">infs2</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == 1) </span><span class="identifier">right_second</span><span class="plain">[</span><span class="identifier">infs2</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">leftc</span><span class="plain"> == 1) </span><span class="identifier">inf1</span><span class="plain"> = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">leftc</span><span class="plain"> == 2) {</span>
<span class="functiontext">Problems::Issue::infs_contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf1</span><span class="plain">), </span><span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">),</span>
<span class="identifier">infs</span><span class="plain">, </span><span class="string">"can only relate to one other thing in this way"</span><span class="plain">,</span>
<span class="string">"since the relation in question is one-to-one."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_counts</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] &gt;= 2) {</span>
<span class="functiontext">Problems::Issue::infs_contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_Relation1to1Right</span><span class="plain">),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">right_first</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">right_second</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]),</span>
<span class="identifier">infs</span><span class="plain">, </span><span class="string">"can only relate to one other thing in this way"</span><span class="plain">,</span>
<span class="string">"since the relation in question is one-to-one."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">right_second</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">right_first</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">right_counts</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *));</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::check_OtoV_relation</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nc</span><span class="plain"> = </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">right_counts</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain"> *)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference</span><span class="plain"> **</span><span class="identifier">right_first</span><span class="plain"> = (</span><span class="reserved">inference</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference</span><span class="plain"> **</span><span class="identifier">right_second</span><span class="plain"> = (</span><span class="reserved">inference</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">left_counts</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain"> *)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference</span><span class="plain"> **</span><span class="identifier">left_first</span><span class="plain"> = (</span><span class="reserved">inference</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference</span><span class="plain"> **</span><span class="identifier">left_second</span><span class="plain"> = (</span><span class="reserved">inference</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *), </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">));</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) </span><span class="identifier">right_counts</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] = 0;</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::as_subject</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">), </span><span class="constant">ARBITRARY_RELATION_INF</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">left_val</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">right_val</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">World::Inferences::get_references_spec</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, &amp;</span><span class="identifier">left_val</span><span class="plain">, &amp;</span><span class="identifier">right_val</span><span class="plain">);</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">left_infs</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::from_specification</span><span class="plain">(</span><span class="identifier">left_val</span><span class="plain">);</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">right_infs</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::from_specification</span><span class="plain">(</span><span class="identifier">right_val</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">left_id</span><span class="plain"> = (</span><span class="identifier">left_infs</span><span class="plain">)?(</span><span class="identifier">left_infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">):(-1);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">right_id</span><span class="plain"> = (</span><span class="identifier">right_infs</span><span class="plain">)?(</span><span class="identifier">right_infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">):(-1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_id</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> = </span><span class="identifier">left_counts</span><span class="plain">[</span><span class="identifier">left_id</span><span class="plain">]++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == 0) </span><span class="identifier">left_first</span><span class="plain">[</span><span class="identifier">left_id</span><span class="plain">] = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == 1) </span><span class="identifier">left_second</span><span class="plain">[</span><span class="identifier">left_id</span><span class="plain">] = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_id</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> = </span><span class="identifier">right_counts</span><span class="plain">[</span><span class="identifier">right_id</span><span class="plain">]++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == 0) </span><span class="identifier">right_first</span><span class="plain">[</span><span class="identifier">right_id</span><span class="plain">] = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == 1) </span><span class="identifier">right_second</span><span class="plain">[</span><span class="identifier">right_id</span><span class="plain">] = </span><span class="identifier">inf</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> == </span><span class="constant">Relation_VtoO</span><span class="plain">) {</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_counts</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] &gt;= 2) {</span>
<span class="functiontext">Problems::Issue::infs_contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelationVtoOContradiction</span><span class="plain">),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">left_first</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">left_second</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]),</span>
<span class="identifier">infs</span><span class="plain">, </span><span class="string">"can only relate to one other thing in this way"</span><span class="plain">,</span>
<span class="string">"since the relation in question is various-to-one."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_counts</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] &gt;= 2) {</span>
<span class="functiontext">Problems::Issue::infs_contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RelationOtoVContradiction</span><span class="plain">),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">right_first</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]),</span>
<span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">right_second</span><span class="plain">[</span><span class="identifier">infs</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">]),</span>
<span class="identifier">infs</span><span class="plain">, </span><span class="string">"can only be related to by one other thing in this way"</span><span class="plain">,</span>
<span class="string">"since the relation in question is one-to-various."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">right_second</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">right_first</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">right_counts</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">left_second</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">left_first</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">inference</span><span class="plain"> *));</span>
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">left_counts</span><span class="plain">, </span><span class="constant">OBJECT_COMPILATION_MREASON</span><span class="plain">, </span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">int</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::check_OtoO_relation is used in 6/bp (<a href="6-bp.html#SP33">&#167;33</a>).</p>
<p class="endnote">The function Relations::check_OtoV_relation is used in 6/bp (<a href="6-bp.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. Generating routines to test relations by condition. </b>When a relation has to be tested as a condition, we can't simply embed that
condition as the I6 schema for "test relation": it might very well need
local variables, the table row-choosing variables, etc., to evaluate. It
has to be tested in its own context. So we generate a routine called
<code class="display"><span class="extract">Relation_X</span></code>, where <code class="display"><span class="extract">X</span></code> is the allocation ID number of the BP, which takes
two parameters <code class="display"><span class="extract">t_0</span></code> and <code class="display"><span class="extract">t_1</span></code> and returns true or false according to
whether or not R(<code class="display"><span class="extract">t_0</span></code>, <code class="display"><span class="extract">t_1</span></code>).
</p>
<p class="inwebparagraph">This is where those routines are compiled.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_defined_relations</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Relations::compile_relation_records</span><span class="plain">();</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain"> == </span><span class="constant">Relation_ByRoutine</span><span class="plain">) &amp;&amp; (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain">)) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_created_at</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"Routine to decide if %S(t_0, t_1)"</span><span class="plain">, </span><span class="functiontext">BinaryPredicates::get_log_name</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="identifier">Produce::comment</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Relations::compile_routine_to_decide</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_by_routine_iname</span><span class="plain">,</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;condition_defn_text</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0], </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1]);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Compile RProperty routine</span> <span class="cwebmacronumber">29.1</span>&gt;<span class="plain">;</span>
<span class="reserved">relation_guard</span><span class="plain"> *</span><span class="identifier">rg</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">, </span><span class="reserved">relation_guard</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Compile RGuard f0 routine</span> <span class="cwebmacronumber">29.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile RGuard f1 routine</span> <span class="cwebmacronumber">29.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile RGuard T routine</span> <span class="cwebmacronumber">29.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile RGuard MT routine</span> <span class="cwebmacronumber">29.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile RGuard MF routine</span> <span class="cwebmacronumber">29.6</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_defined_relations is used in 1/mr (<a href="1-mr.html#SP4_14">&#167;4.14</a>).</p>
<p class="inwebparagraph"><a id="SP29_1"></a><b>&#167;29.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RProperty routine</span> <span class="cwebmacronumber">29.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RPROPERTY_HL</span><span class="plain">));</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">obj_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"obj"</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">cl_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"cl"</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">pr_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"pr"</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">obj_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">cl_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PROPERTYVALUE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">obj_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">pr_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_nothing</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP29_2"></a><b>&#167;29.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RGuard f0 routine</span> <span class="cwebmacronumber">29.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f0_iname</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f0_iname</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">X_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">X_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"X"</span><span class="plain">, </span><span class="string">"which is related to at most one object"</span><span class="plain">, &amp;</span><span class="identifier">X_lv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Schemas::emit_val_expand_from_locals</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f0</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_nothing</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_nothing</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP29_3"></a><b>&#167;29.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RGuard f1 routine</span> <span class="cwebmacronumber">29.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f1_iname</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_f1_iname</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">X_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">X_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"X"</span><span class="plain">, </span><span class="string">"which is related to at most one object"</span><span class="plain">, &amp;</span><span class="identifier">X_lv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f1</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">X_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Calculus::Schemas::emit_val_expand_from_locals</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;f1</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">, </span><span class="identifier">X_lv</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_nothing</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_nothing</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP29_4"></a><b>&#167;29.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RGuard T routine</span> <span class="cwebmacronumber">29.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_test_iname</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_test_iname</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">L_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">R_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">L_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"L"</span><span class="plain">, </span><span class="string">"left member of pair"</span><span class="plain">, &amp;</span><span class="identifier">L_lv</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">R_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"R"</span><span class="plain">, </span><span class="string">"right member of pair"</span><span class="plain">, &amp;</span><span class="identifier">R_lv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_test</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">downs</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">L_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">downs</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">downs</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="functiontext">Calculus::Schemas::emit_val_expand_from_locals</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_test</span><span class="plain">, </span><span class="identifier">L_lv</span><span class="plain">, </span><span class="identifier">R_lv</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">downs</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP29_5"></a><b>&#167;29.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RGuard MT routine</span> <span class="cwebmacronumber">29.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_true_iname</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_true_iname</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">L_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">R_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">L_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"L"</span><span class="plain">, </span><span class="string">"left member of pair"</span><span class="plain">, &amp;</span><span class="identifier">L_lv</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">R_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"R"</span><span class="plain">, </span><span class="string">"right member of pair"</span><span class="plain">, &amp;</span><span class="identifier">R_lv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_make_true</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">downs</span><span class="plain"> = 1;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">downs</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) &amp;&amp; (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">downs</span><span class="plain"> = 2;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">L_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">downs</span><span class="plain">-1; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_make_true</span><span class="plain">, </span><span class="identifier">L_lv</span><span class="plain">, </span><span class="identifier">R_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> &gt; 0) { </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); }</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RUNTIMEPROBLEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RTP_RELKINDVIOLATION_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">L_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guarding</span><span class="plain">-</span><span class="element">&gt;bp_iname</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP29_6"></a><b>&#167;29.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RGuard MF routine</span> <span class="cwebmacronumber">29.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_false_iname</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guard_make_false_iname</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">L_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">R_lv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">L_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"L"</span><span class="plain">, </span><span class="string">"left member of pair"</span><span class="plain">, &amp;</span><span class="identifier">L_lv</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">R_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"R"</span><span class="plain">, </span><span class="string">"right member of pair"</span><span class="plain">, &amp;</span><span class="identifier">R_lv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_make_false</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">downs</span><span class="plain"> = 1;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">downs</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) &amp;&amp; (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">downs</span><span class="plain"> = 2;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">L_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_L</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OFCLASS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;check_R</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">downs</span><span class="plain">-1; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_locals</span><span class="plain">(</span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;inner_make_false</span><span class="plain">, </span><span class="identifier">L_lv</span><span class="plain">, </span><span class="identifier">R_lv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> &gt; 0) { </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); }</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RUNTIMEPROBLEM_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RTP_RELKINDVIOLATION_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">L_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rg</span><span class="plain">-</span><span class="element">&gt;guarding</span><span class="plain">-</span><span class="element">&gt;bp_iname</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP30"></a><b>&#167;30. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::compile_routine_to_decide</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">rname</span><span class="plain">,</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">par1</span><span class="plain">, </span><span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">par2</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">rname</span><span class="plain">);</span>
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
<span class="functiontext">BinaryPredicates::add_term_as_call_parameter</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">par1</span><span class="plain">);</span>
<span class="functiontext">BinaryPredicates::add_term_as_call_parameter</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">par2</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::enable_possessive_form_of_it</span><span class="plain">();</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">condition</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="functiontext">Dash::validate_conditional_clause</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadRelationCondition</span><span class="plain">),</span>
<span class="string">"the condition defining this relation makes no sense to me"</span><span class="plain">,</span>
<span class="string">"although the definition was properly formed - it is only "</span>
<span class="string">"the part after 'when' which I can't follow."</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_routine_to_decide is used in <a href="#SP29">&#167;29</a>.</p>
<p class="inwebparagraph"><a id="SP31"></a><b>&#167;31. Indexing relations. </b>A brief table of relations appears on the Phrasebook Index page.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::index_table</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">;</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML::begin_plain_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;i&gt;name&lt;/i&gt;"</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;i&gt;category&lt;/i&gt;"</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;i&gt;relates this...&lt;/i&gt;"</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;i&gt;...to this&lt;/i&gt;"</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">type</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">left</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">right</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_family</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">EQUALITY_KBP</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"equality"</span><span class="plain">; </span><span class="identifier">left</span><span class="plain"> = </span><span class="string">"&lt;i&gt;any&lt;/i&gt;"</span><span class="plain">; </span><span class="identifier">right</span><span class="plain"> = </span><span class="identifier">left</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">QUASINUMERIC_KBP</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"numeric"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"spatial"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MAP_CONNECTING_KBP</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"map"</span><span class="plain">; </span><span class="identifier">left</span><span class="plain"> = </span><span class="string">"room/door"</span><span class="plain">; </span><span class="identifier">right</span><span class="plain"> = </span><span class="identifier">left</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROVISION_KBP</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"provision"</span><span class="plain">; </span><span class="identifier">left</span><span class="plain"> = </span><span class="string">"&lt;i&gt;any&lt;/i&gt;"</span><span class="plain">; </span><span class="identifier">right</span><span class="plain"> = </span><span class="string">"property"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">EXPLICIT_KBP</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;form_of_relation</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoO</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"one-to-one"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_OtoV</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"one-to-various"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoO</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"various-to-one"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_VtoV</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"various-to-various"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_OtoO</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"one-to-another"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Sym_VtoV</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"various-to-each-other"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_Equiv</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"in groups"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">Relation_ByRoutine</span><span class="plain">: </span><span class="identifier">type</span><span class="plain"> = </span><span class="string">"defined"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">type</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="identifier">WordAssemblages::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_created_at</span><span class="plain">) </span><span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_created_at</span><span class="plain">)));</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">type</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">type</span><span class="plain">); </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--"</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="functiontext">BinaryPredicates::index_term_details</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[0]));</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="functiontext">BinaryPredicates::index_term_details</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[1]));</span>
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::index_table appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP32"></a><b>&#167;32. </b>And a briefer note still for the table of verbs.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Relations::index_for_verbs</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" ... &lt;i&gt;"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(a meaning internal to Inform)"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;right_way_round</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">bp</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"reversed "</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WordAssemblages::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, &amp;(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;/i&gt;"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::index_for_verbs is used in 6/nv (<a href="6-nv.html#SP25">&#167;25</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="6-bp.html">Back to 'Binary Predicates'</a></li><li><a href="6-er.html">Continue with 'Explicit Relations'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>