1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/6-bp.html
2020-01-27 01:22:21 +00:00

1507 lines
192 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>5/ipw</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/bp' 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>Binary Predicates</b></li></ul><p class="purpose">To create and manage binary predicates, which are the underlying data structures beneath Inform's relations.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP18">&#167;18. Creating term details</a></li><li><a href="#SP27">&#167;27. Making the equality relation</a></li><li><a href="#SP28">&#167;28. Making a pair of relations</a></li><li><a href="#SP30">&#167;30. BP construction</a></li><li><a href="#SP31">&#167;31. The package</a></li><li><a href="#SP32">&#167;32. The handler</a></li><li><a href="#SP33">&#167;33. As an INFS</a></li><li><a href="#SP34">&#167;34. BP and term logging</a></li><li><a href="#SP35">&#167;35. Relation names</a></li><li><a href="#SP37">&#167;37. Miscellaneous access routines</a></li><li><a href="#SP45">&#167;45. The built-in BPs</a></li><li><a href="#SP46">&#167;46. Other property-based relations</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>A "binary predicate" (the term comes from logic) is a property B
such that for any combination x and y, and at any given moment at
run-time, B(x, y) is either true or false.
</p>
<p class="inwebparagraph">Examples used in Inform include equality, where EQ(x, y) is true if and
only if x = y, and containment, where C(x, y) is true if and only if the
thing x is inside the room or container y. (EQ does not change
during play, but C does.) A fairly large set of binary predicates is built
into Inform, and the user is allowed to create more with sentences like
</p>
<blockquote>
<p>Lock-fitting relates one thing (called the matching key) to various things.</p>
</blockquote>
<p class="inwebparagraph">In the Inform documentation, binary predicates are called "relations".
The code to parse "relates" sentences and construct the binary predicate
implied can be found in the next section, "Relations.w".
</p>
<p class="inwebparagraph">Binary predicates are of central importance because they allow complex
sentences to be written which talk about more than one thing at a time,
with some connection between them. In excerpts like "an animal inside
something" or "a man who wears the top hat", the meanings of the two
connecting pieces of text &mdash; "inside" and "who wears" &mdash; are (pointers
to) binary predicates: the containment relation and the wearing relation.
</p>
<p class="inwebparagraph">Inform is rich in ways to create relations, and consequently the BPs are
many and varied. They turn up in one-off examples but also in whole families.
Still, despite the variation, what they share in common is greater yet,
and so a single <code class="display"><span class="extract">binary_predicate</span></code> structure is used to represent them all.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The values x and y to which a binary predicate B can apply are
called its "terms". For some relations, the source text gives these
names:
</p>
<blockquote>
<p>Lock-fitting relates one thing (called the matching key) to various things.</p>
</blockquote>
<p class="inwebparagraph">Here the x term has the name "matching key", whereas the y term is
anonymous. (More often, both are anonymous.) Internally the terms are not
named but are numbered 0 and 1: so we should really write B(x_0, x_1)
rather than B(x, y).
</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Different BPs apply to different sorts of terms: for instance, the
numerical less-than comparison applies to numbers, whereas containment
applies to things. The two terms need not have the same domain: the
"wearing" relation, as seen in
</p>
<blockquote>
<p>Harry Smythe wears the tweed waistcoat.</p>
</blockquote>
<p class="inwebparagraph">is a binary predicate W(x_0, x_1) such that x_0 ranges across people
and x_1 ranges across things.
</p>
<p class="inwebparagraph">Inform represents this by allowing each BP to have either a
designated kind of object, or a designated kind of value, or no
restriction at all, for each term. (In practice, even the unrestricted
terms have limitations, but which are enforced by special code in the
type-checker to handle special predicates such as equality. For instance,
EQ(x, y) can be tested for any values x and y of the same kind, so
the two terms in effect constrain each other.)
</p>
<p class="inwebparagraph">In the S-parser, type-checking is used to make sure the source text doesn't
try to test or assert B(x, y) for any x or y which don't fit, so that
</p>
<blockquote>
<p>if 1 wears "Hello there", ...</p>
</blockquote>
<p class="inwebparagraph">will be rejected. Whereas in the A-parser, these restrictions are used to
infer information about otherwise unknown quantities: so writing
</p>
<blockquote>
<p>Harry Smythe wears the tweed waistcoat.</p>
</blockquote>
<p class="inwebparagraph">causes the A-parser to force the Harry Smythe object to be of kind
"person", and the tweed waistcoat of kind "thing".
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Some BPs are such that B(x, y) can be true for more or less any
combination of x and y. Those can take a lot of storage and it is
difficult to perform any reasoning about them, because knowing that B(x,
y) is true doesn't give you any information about B(x, z). For instance,
the BP created by
</p>
<blockquote>
<p>Suspicion relates various people to various people.</p>
</blockquote>
<p class="inwebparagraph">is stored at run-time in a bitmap of P^2 bits, where P is the number
of people, and searching it ("if anyone suspects Harry") requires
exhaustive loops, which incur some speed overhead as well.
</p>
<p class="inwebparagraph">But other BPs have special properties restricting the circumstances in
which they are true, and in those cases we want to capitalise on that.
"Contains" is an example of this. A single thing y can be (directly)
inside only one other thing x at a time, so that if we know C(x, y)
and C(w, y) then we can deduce that x=w. We write this common value
as f_0(y), the only possible value for term 0 given that term 1 is y.
Another way to say this is that the only possible pairs making C true
have the form C(f_0(y), y).
</p>
<p class="inwebparagraph">And similarly for term 1. If we write T for the "on top of" relation
then it turns out that there is a function f_1 such that the only cases
where T is true have the form T(x, f_1(x)). Here f_1(x) is the thing
which directly supports x.
</p>
<p class="inwebparagraph">Containment has an f_0 but not an f_1 function; "on top of" has an
f_1 but not an f_0. Many BPs (like "suspicion" above) have neither.
</p>
<p class="inwebparagraph">Note that if B does have an f_0 function then its reversal R has an
identical f_1 function, and vice versa.
</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>We never in fact need to calculate the value of f_0(y) from y during
compilation &mdash; only at run-time. So we store the function f_0(y) as what
is called an "I6 schema", basically a piece of I6 source code with a
place-holder where y is to be inserted. In the case of containment, the
schema is written
f_0(<code class="display"><span class="extract">*1</span></code>) = <code class="display"><span class="extract">ContainerOf(*1)</span></code>
and what this means is that we can calculate f_0(y) from an object y
at run-time by calling the <code class="display"><span class="extract">ContainerOf</span></code> function, which tells us what
container (if any) is at present directly containing y.
</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>To sum up, each term of a BP can specify: a name, a domain, and an
f_i function. Every one of these details is optional. They are gathered
together in a sub-structure called <code class="display"><span class="extract">bp_term_details</span></code>.
</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">bp_term_details</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">called_name</span><span class="plain">; </span> <span class="comment">"(called...)" name, if any exists</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">implies_infs</span><span class="plain">; </span> <span class="comment">the domain of values allowed</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">implies_kind</span><span class="plain">; </span> <span class="comment">the kind of these values</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">function_of_other</span><span class="plain">; </span> <span class="comment">the function f_0 or f_1 as above</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">index_term_as</span><span class="plain">; </span> <span class="comment">usually null, but if not, used in Phrasebook index</span>
<span class="plain">} </span><span class="reserved">bp_term_details</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure bp_term_details is private to this section.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Given any binary predicate B, we may wish to do some or all of the
following at run-time:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Test whether or not B(x, y) is true at run-time. Here Inform
needs to compile an I6 condition.
</li></ul>
<ul class="items"><li>(b) Assert that B(x, y) is true in the assertion sentences of
the source text. Inform will need to remember all pairs x, y for which B
has been asserted so that it can compile this information as the original
state of the I6 data structure containing the current state of B.
</li></ul>
<ul class="items"><li>(c) Set B(x, y) true, or false, at run-time. Here Inform needs to
compile I6 code which will modify that data structure.
</li></ul>
<p class="inwebparagraph">Some BPs provide an I6 schema to achieve (a), others provide (a) and (b),
while a happy few provide all of (a), (b), (c).
</p>
<p class="inwebparagraph">The variety of BPs is such that different BPs use very different run-time
mechanisms. Some relations compile elaborate routines to test (a), some
look at parents or chidren in the I6 object tree, some look at I6 property
values, others look inside bitmaps. The actual work is often done by routines
in the I6 template, which are called by code generated by the I6 schema for
(a); and similarly for (b) and (c).
</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Each BP has a partner which we call its "reversal". If B is the
original and R is its reversal, then B(x, y) is true if and only if
R(y, x) is true. Reversals sometimes occur quite naturally in English
language. "To wear" is the reversal of "to be worn by". "Contains" is
the reversal of being "inside". (Though not every BP has an interesting
reversal. The reversal of "is" &mdash; equality &mdash; looks much the same as the
original, because x=y if and only if y=x.)
</p>
<p class="inwebparagraph">The following sentences express the same fact:
</p>
<blockquote>
<p>The ball is inside the trophy case.</p>
</blockquote>
<blockquote>
<p>The trophy case contains the ball.</p>
</blockquote>
<p class="inwebparagraph">...but when we parse them into their meanings, we could easily lose sight
that they are saying the same thing, because they involve different BPs:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">inside(ball, trophy case)| and |contains(trophy case, ball)</span>
</pre>
<p class="inwebparagraph">It's usually a bad idea for any computer program to represent the same
conceptual idea in more than one way. So for every pair of BPs X and Y
which are each other's reversal, Inform designates one as being
"the right way round" and the other as being "the wrong way round".
Whenever a sentence's meaning involves a BP which is "the wrong way
round", Inform swaps over the terms and replaces the BP by its reversal,
which is "the right way round". That makes it much easier to recognise
when pairs of sentences like the one above are duplicating each other's
meanings.
</p>
<p class="inwebparagraph">This is purely an internal implementation trick. There's no natural sense
in language or mathematics in which "contains" is the right way round
and "inside" the wrong way round.
</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>We can finally now declare the epic BP structure.
</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">binary_predicate</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">relation_family</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">*_KBP</span></code> constants defined below</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">form_of_relation</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">Relation_*</span></code> constants defined below</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">relation_name</span><span class="plain">; </span> <span class="comment">(which might have length 0)</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">bp_created_at</span><span class="plain">; </span> <span class="comment">where declared in the source text</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">debugging_log_name</span><span class="plain">; </span> <span class="comment">used when printing propositions to the debug log</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">bp_package</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">bp_iname</span><span class="plain">; </span> <span class="comment">when referred to as a constant</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">handler_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">v2v_bitmap_iname</span><span class="plain">; </span> <span class="comment">only relevant for some relations</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">term_details</span><span class="plain">[2]; </span> <span class="comment">term 0 is the left term, 1 is the right</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">reversal</span><span class="plain">; </span> <span class="comment">the R such that R(x,y) iff B(y,x)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">right_way_round</span><span class="plain">; </span> <span class="comment">was this BP created directly? or is it a reversal of another?</span>
<span class="comment">how to compile code which tests or forces this BP to be true or false:</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">bp_by_routine_iname</span><span class="plain">; </span> <span class="comment">for relations by routine</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">test_function</span><span class="plain">; </span> <span class="comment">I6 schema for (a) testing B(x, y)...</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">condition_defn_text</span><span class="plain">; </span> <span class="comment">...unless this I7 condition is used instead</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">make_true_function</span><span class="plain">; </span> <span class="comment">I6 schema for (b) "now B(x, y)"</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">make_false_function</span><span class="plain">; </span> <span class="comment">I6 schema for (c) "now not(B(x, y))"</span>
<span class="comment">for use in the A-parser:</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">arbitrary</span><span class="plain">; </span> <span class="comment">allow source to assert B(x, y) for any arbitrary pairs x, y</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">set_property</span><span class="plain">; </span> <span class="comment">asserting B(x, v) sets this prop. of x to v</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">property_pending_text</span><span class="plain">; </span> <span class="comment">temp. version used until props created</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">relates_values_not_objects</span><span class="plain">; </span> <span class="comment">true if either term is necessarily a value...</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">knowledge_about_bp</span><span class="plain">; </span> <span class="comment">...and if so, here's the list of known assertions</span>
<span class="comment">for optimisation of run-time code:</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dynamic_memory</span><span class="plain">; </span> <span class="comment">stored in dynamically allocated memory</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">initialiser_iname</span><span class="plain">; </span> <span class="comment">and if so, this is the name of its initialiser</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">i6_storage_property</span><span class="plain">; </span> <span class="comment">provides run-time storage</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">storage_kind</span><span class="plain">; </span> <span class="comment">kind of property owner</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_function_simplification</span><span class="plain">; </span> <span class="comment">allow Inform to make use of any f_i functions?</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fast_route_finding</span><span class="plain">; </span> <span class="comment">use fast rather than slow route-finding algorithm?</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">loop_parent_optimisation_proviso</span><span class="plain">; </span> <span class="comment">if not NULL, optimise loops using object tree</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">loop_parent_optimisation_ranger</span><span class="plain">; </span> <span class="comment">if not NULL, routine iterating through contents</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">record_needed</span><span class="plain">; </span> <span class="comment">we need to compile a small array of details in readable memory</span>
<span class="comment">details, filled in for right-way-round BPs only, for particular kinds of BP:</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">a_listed_in_predicate</span><span class="plain">; </span> <span class="comment">(if right way) was this generated from a table column?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">same_property</span><span class="plain">; </span> <span class="comment">(if right way) if a "same property as..."</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">comparative_property</span><span class="plain">; </span> <span class="comment">(if right way) if a comparative adjective</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">comparison_sign</span><span class="plain">; </span> <span class="comment">...and <code class="display"><span class="extract">+1</span></code> or <code class="display"><span class="extract">-1</span></code> according to sign of definition</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">equivalence_partition</span><span class="plain">; </span> <span class="comment">(if right way) partition array of equivalence classes</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">binary_predicate</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure binary_predicate is accessed in 6/rlt, 6/nv, 15/cr, 15/spr, 15/spr2, 19/lr and here.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>This seems a good point to lay out a classification of all of the BPs
existing within Inform. Broadly, they divide into two: the ones explicitly
created by the source text, in sentences like
</p>
<blockquote>
<p>Admiration relates various people to various people.</p>
</blockquote>
<p class="inwebparagraph">These are called "explicit". The others are "implicit" and are either
created automatically soon after Inform starts up, or else are created as
a consequence of something else being created by the source text, such as
</p>
<blockquote>
<p>Definition: A woman is tall if her height is 68 or more.</p>
</blockquote>
<p class="inwebparagraph">which implicitly creates a "taller than" relation. All explicit BPs are
constructed in the "Relations.w" section of the source code.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">EQUALITY_KBP</span><span class="plain"> 1 </span> <span class="comment">there is exactly one of these: the x=y predicate</span>
<span class="definitionkeyword">define</span> <span class="constant">QUASINUMERIC_KBP</span><span class="plain"> 2 </span> <span class="comment">the inequality comparison &lt;=, &lt; and so on</span>
<span class="definitionkeyword">define</span> <span class="constant">SPATIAL_KBP</span><span class="plain"> 3 </span> <span class="comment">a relation associated with a map connection</span>
<span class="definitionkeyword">define</span> <span class="constant">MAP_CONNECTING_KBP</span><span class="plain"> 4 </span> <span class="comment">a relation associated with a map connection</span>
<span class="definitionkeyword">define</span> <span class="constant">PROPERTY_SETTING_KBP</span><span class="plain"> 5 </span> <span class="comment">a relation associated with a value property</span>
<span class="definitionkeyword">define</span> <span class="constant">PROPERTY_SAME_KBP</span><span class="plain"> 6 </span> <span class="comment">another relation associated with a value property</span>
<span class="definitionkeyword">define</span> <span class="constant">PROPERTY_COMPARISON_KBP</span><span class="plain"> 7 </span> <span class="comment">another relation associated with a value property</span>
<span class="definitionkeyword">define</span> <span class="constant">LISTED_IN_KBP</span><span class="plain"> 8 </span> <span class="comment">a relation for indirect table lookups, one for each column name</span>
<span class="definitionkeyword">define</span> <span class="constant">PROVISION_KBP</span><span class="plain"> 9 </span> <span class="comment">a relation for specifying which objects provide which properties</span>
<span class="definitionkeyword">define</span> <span class="constant">UNIVERSAL_KBP</span><span class="plain"> 10 </span> <span class="comment">a relation for applying general other relations</span>
<span class="definitionkeyword">define</span> <span class="constant">EXPLICIT_KBP</span><span class="plain"> 100 </span> <span class="comment">defined explicitly in the source text; the others are all implicit</span>
</pre>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>The following constants are used to identify the "form" of a BP (in that the
<code class="display"><span class="extract">form_of_relation</span></code> field of any BP always equals one of these and never changes).
These constant names (and values) exactly match a set of constants compiled
into every I6 program created by Inform, so they can be used freely both in
the Inform source code and also in the I6 template layer.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">Relation_Implicit</span><span class="plain"> -1 </span> <span class="comment">all implicit BPs have this form, and all others are explicit</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_OtoO</span><span class="plain"> 1 </span> <span class="comment">one to one: "R relates one K to one K"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_OtoV</span><span class="plain"> 2 </span> <span class="comment">one to various: "R relates one K to various K"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_VtoO</span><span class="plain"> 3 </span> <span class="comment">various to one: "R relates various K to one K"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_VtoV</span><span class="plain"> 4 </span> <span class="comment">various to various: "R relates various K to various K"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_Sym_OtoO</span><span class="plain"> 5 </span> <span class="comment">symmetric one to one: "R relates one K to another"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_Sym_VtoV</span><span class="plain"> 6 </span> <span class="comment">symmetric various to various: "R relates K to each other"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_Equiv</span><span class="plain"> 7 </span> <span class="comment">equivalence relation: "R relates K to each other in groups"</span>
<span class="definitionkeyword">define</span> <span class="constant">Relation_ByRoutine</span><span class="plain"> 8 </span> <span class="comment">relation tested by a routine: "R relates K to L when (some condition)"</span>
</pre>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>That completes the catalogue of the one-off cases, and we can move on
to the five families of implicit relations which correspond to other
structures in the source text.
</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>The second family of implicit relations corresponds to any property which has
been given as the meaning of a verb, as in the example
</p>
<blockquote>
<p>The verb to weigh (it weighs, they weigh, it is weighing) implies the weight property.</p>
</blockquote>
<p class="inwebparagraph">This implicitly constructs a relation W(p, w) where p is a thing and
w a weight.
</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>The third family corresponds to defined adjectives which perform a
numerical comparison in a particular way, as here:
</p>
<blockquote>
<p>Definition: A woman is tall if her height is 68 or more.</p>
</blockquote>
<p class="inwebparagraph">This implicitly constructs a relation T(x, y) which is true if and only
if woman x is taller than woman y.
</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>The fourth family corresponds to value properties, so that
</p>
<blockquote>
<p>A door has a number called street number.</p>
</blockquote>
<p class="inwebparagraph">implicitly constructs a relation SN(d_1, d_2) which is true if and only if
doors d_1 and d_2 have the same street number.
</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>The fifth family corresponds to names of table columns. If any table includes
a column headed "eggs per clutch" then that will implicitly construct a
relation LEPC(n, T) which is true if and only if the number n is listed
as one of the eggs-per-clutch entries in the table T, where T has to be
one of the tables which has a column of this name.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_TYPE</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">binary_predicate</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_REVERSAL</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::get_reversal</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_EQUALITY</span><span class="plain"> </span><span class="identifier">R_equality</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_UNIVERSAL</span><span class="plain"> </span><span class="identifier">R_universal</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_POSSESSION</span><span class="plain"> </span><span class="identifier">a_has_b_predicate</span>
</pre>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Creating term details. </b>The essential point in defining a term is to describe the domain of values it
ranges over, which we do by giving an "inference subject" (INFS). An INFS is
roughly speaking anything in the model world which Inform can store knowledge
about; here it will almost always be a generality of things, such as "all
numbers", or "all rooms".
</p>
<pre class="display">
<span class="reserved">bp_term_details</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::new_term</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">bp_term_details</span><span class="plain"> </span><span class="identifier">bptd</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.called_name</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.function_of_other</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.implies_infs</span><span class="plain"> = </span><span class="identifier">infs</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.implies_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.index_term_as</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">bptd</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::new_term is used in <a href="#SP19">&#167;19</a>, <a href="#SP27">&#167;27</a>, <a href="#SP29">&#167;29</a>, 6/tur (<a href="6-tur.html#SP3">&#167;3</a>), 12/ter (<a href="12-ter.html#SP3">&#167;3</a>), 12/qr (<a href="12-qr.html#SP3">&#167;3</a>), 15/tpr (<a href="15-tpr.html#SP3">&#167;3</a>), 15/ma (<a href="15-ma.html#SP14_2">&#167;14.2</a>), 15/spr (<a href="15-spr.html#SP2">&#167;2</a>), 15/spr2 (<a href="15-spr2.html#SP2">&#167;2</a>), 19/lr (<a href="19-lr.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>And there is also a fuller version, including the inessentials:
</p>
<pre class="display">
<span class="reserved">bp_term_details</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::full_new_term</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">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">,</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CW</span><span class="plain">, </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">f</span><span class="plain">) {</span>
<span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">bptd</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::new_term</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
<span class="identifier">bptd</span><span class="element">.implies_kind</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.called_name</span><span class="plain"> = </span><span class="identifier">CW</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="element">.function_of_other</span><span class="plain"> = </span><span class="identifier">f</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">bptd</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::full_new_term is used in 6/rlt (<a href="6-rlt.html#SP9_3_1">&#167;9.3.1</a>), 12/ter (<a href="12-ter.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>In a few cases BPs need to be created before the relevant domains are known,
so that we must fill them in later, using the following:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::set_term_domain</span><span class="plain">(</span><span class="reserved">bp_term_details</span><span class="plain"> *</span><span class="identifier">bptd</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">bptd</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 BPTD"</span><span class="plain">);</span>
<span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_kind</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::set_term_domain is used in 15/spr2 (<a href="15-spr2.html#SP8">&#167;8</a>), 19/lr (<a href="19-lr.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>Similarly:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::set_term_function</span><span class="plain">(</span><span class="reserved">bp_term_details</span><span class="plain"> *</span><span class="identifier">bptd</span><span class="plain">, </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">f</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</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 BPTD"</span><span class="plain">);</span>
<span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;function_of_other</span><span class="plain"> = </span><span class="identifier">f</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_term_function</span><span class="plain">(</span><span class="reserved">bp_term_details</span><span class="plain"> *</span><span class="identifier">bptd</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</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 BPTD"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;function_of_other</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::set_term_function is used in 6/rlt (<a href="6-rlt.html#SP9">&#167;9</a>, <a href="6-rlt.html#SP9_14">&#167;9.14</a>).</p>
<p class="endnote">The function BinaryPredicates::get_term_function is used in 6/rlt (<a href="6-rlt.html#SP9">&#167;9</a>).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>Combining these:
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::kind</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">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> == </span><span class="identifier">R_equality</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_relation</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K0</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::kind_of_term</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">kind</span><span class="plain"> *</span><span class="identifier">K1</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::kind_of_term</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="reserved">if</span><span class="plain"> (</span><span class="identifier">K0</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K0</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">K1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K1</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_relation</span><span class="plain">, </span><span class="identifier">K0</span><span class="plain">, </span><span class="identifier">K1</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::kind is used in 6/rlt (<a href="6-rlt.html#SP15">&#167;15</a>, <a href="6-rlt.html#SP15_1">&#167;15.1</a>, <a href="6-rlt.html#SP15_1_4">&#167;15.1.4</a>), 14/rv (<a href="14-rv.html#SP23_2">&#167;23.2</a>).</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. </b>The kind of a term is:
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::kind_of_term</span><span class="plain">(</span><span class="reserved">bp_term_details</span><span class="plain"> *</span><span class="identifier">bptd</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</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">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_kind</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_kind</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">InferenceSubjects::domain</span><span class="plain">(</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_infs</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::kind_of_term is used in <a href="#SP22">&#167;22</a>, <a href="#SP25">&#167;25</a>, <a href="#SP38">&#167;38</a>.</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>The table of relations in the index uses the textual name of an INFS, so:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::index_term_details</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">bp_term_details</span><span class="plain"> *</span><span class="identifier">bptd</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;index_term_as</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">bptd</span><span class="plain">-</span><span class="element">&gt;index_term_as</span><span class="plain">); </span><span class="reserved">return</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">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_infs</span><span class="plain">) </span><span class="identifier">W</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_name_text</span><span class="plain">(</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_infs</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">W</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">W</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::index_term_details is used in 6/rlt (<a href="6-rlt.html#SP31">&#167;31</a>).</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>The following routine adds the given BP term as a call parameter to the
routine currently being compiled, deciding that something is an object if
its kind indications are all blank, but verifying that the value supplied
matches the specific necessary kind of object if there is one.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::add_term_as_call_parameter</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="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">bptd</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::kind_of_term</span><span class="plain">(&amp;</span><span class="identifier">bptd</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">K</span><span class="plain">;</span>
<span class="reserved">if</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="identifier">Kinds::Compare::lt</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">PK</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lv_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_call_parameter_as_symbol</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">,</span>
<span class="identifier">bptd</span><span class="element">.called_name</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">Kinds::Compare::lt</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">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">NOT_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">lv_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">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="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="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::add_term_as_call_parameter is used in 6/rlt (<a href="6-rlt.html#SP30">&#167;30</a>).</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b>And as a convenience:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::set_index_details</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">char</span><span class="plain"> *</span><span class="identifier">left</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">right</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left</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="element">.index_term_as</span><span class="plain"> = </span><span class="identifier">left</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="element">&gt;term_details</span><span class="plain">[1]</span><span class="element">.index_term_as</span><span class="plain"> = </span><span class="identifier">left</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right</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="element">.index_term_as</span><span class="plain"> = </span><span class="identifier">right</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="element">&gt;term_details</span><span class="plain">[0]</span><span class="element">.index_term_as</span><span class="plain"> = </span><span class="identifier">right</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::set_index_details is used in 12/ter (<a href="12-ter.html#SP3">&#167;3</a>), 12/qr (<a href="12-qr.html#SP3">&#167;3</a>), 15/tpr (<a href="15-tpr.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. Making the equality relation. </b>As we shall see below, BPs are almost always created in matched pairs. There
is one and only one exception to this rule: the equality predicate where
EQ(x, y) if x = y. Equality plays a special role in the system of logic
we'll be using. Since x = y and y = x are exactly equivalent, it is safe
to make EQ its own reversal; this makes it impossible for equality to occur
"the wrong way round" in any proposition, even one which is not yet fully
simplified.
</p>
<p class="inwebparagraph">There is no fixed domain to which x and y belong: equality can be
used whenever x and y belong to the same domain. Thus "if the score is
12" and "if the location is the Pantheon" are both valid uses of EQ,
where x and y are numbers in the former case and rooms in the latter.
It will take special handling in the type-checker to achieve
this effect. For now, we give EQ entirely blank term details.
</p>
<pre class="display">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::make_equality</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="functiontext">BinaryPredicates::make_single</span><span class="plain">(</span><span class="constant">EQUALITY_KBP</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::new_term</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">), </span><span class="functiontext">BinaryPredicates::new_term</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"is"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">,</span>
<span class="identifier">Preform::Nonparsing::wording</span><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="constant">EQUALITY_RELATION_NAME</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">bp</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">TRUE</span><span class="plain">;</span>
<span class="reserved">return</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 BinaryPredicates::make_equality is used in 12/ter (<a href="12-ter.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Making a pair of relations. </b>Every other BP belongs to a matched pair, in which each is the reversal of
the other, but only one is designated as being "the right way round".
The left-hand term of one behaves like the right-hand term of the other,
and vice versa.
</p>
<p class="inwebparagraph">The BP which is the wrong way round is never used in compilation, because
it will long before that have been reversed, so we only fill in details of
how to compile the BP for the one which is the right way round.
</p>
<pre class="display">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::make_pair</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">family</span><span class="plain">,</span>
<span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">left_term</span><span class="plain">, </span><span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">right_term</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">namer</span><span class="plain">, </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">,</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">mtf</span><span class="plain">, </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">tf</span><span class="plain">, </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">source_name</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">bpr</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">nr</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">) == 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">, </span><span class="string">"nameless"</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">nr</span><span class="plain">, </span><span class="identifier">namer</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">nr</span><span class="plain">) == 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nr</span><span class="plain">, </span><span class="string">"%S-r"</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">);</span>
<span class="identifier">bp</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::make_single</span><span class="plain">(</span><span class="identifier">family</span><span class="plain">, </span><span class="identifier">left_term</span><span class="plain">, </span><span class="identifier">right_term</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">,</span>
<span class="identifier">pn</span><span class="plain">, </span><span class="identifier">mtf</span><span class="plain">, </span><span class="identifier">tf</span><span class="plain">, </span><span class="identifier">source_name</span><span class="plain">);</span>
<span class="identifier">bpr</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::make_single</span><span class="plain">(</span><span class="identifier">family</span><span class="plain">, </span><span class="identifier">right_term</span><span class="plain">, </span><span class="identifier">left_term</span><span class="plain">, </span><span class="identifier">nr</span><span class="plain">,</span>
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">WordAssemblages::lit_0</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">bpr</span><span class="plain">; </span><span class="identifier">bpr</span><span class="plain">-</span><span class="element">&gt;reversal</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;right_way_round</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;right_way_round</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">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">)) {</span>
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">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">name</span><span class="plain">-</span><span class="identifier">formal</span><span class="plain">&gt;, 0, </span><span class="identifier">source_name</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain"> = </span><span class="identifier">WordAssemblages::to_wording</span><span class="plain">(&amp;</span><span class="identifier">wa</span><span class="plain">);</span>
<span class="identifier">Nouns::new_proper_noun</span><span class="plain">(</span><span class="identifier">AW</span><span class="plain">, </span><span class="identifier">NEUTER_GENDER</span><span class="plain">,</span>
<span class="identifier">REGISTER_SINGULAR_NTOPT</span><span class="plain"> + </span><span class="identifier">PARSE_EXACTLY_NTOPT</span><span class="plain">,</span>
<span class="identifier">MISCELLANEOUS_MC</span><span class="plain">, </span><span class="functiontext">Rvalues::from_binary_predicate</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">return</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 BinaryPredicates::make_pair is used in <a href="#SP29">&#167;29</a>, 6/tur (<a href="6-tur.html#SP3">&#167;3</a>), 12/ter (<a href="12-ter.html#SP3">&#167;3</a>), 12/qr (<a href="12-qr.html#SP3">&#167;3</a>), 15/tpr (<a href="15-tpr.html#SP3">&#167;3</a>), 15/ma (<a href="15-ma.html#SP14_2">&#167;14.2</a>), 15/spr (<a href="15-spr.html#SP2">&#167;2</a>), 15/spr2 (<a href="15-spr2.html#SP2">&#167;2</a>), 19/lr (<a href="19-lr.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. </b>When the source text declares new relations, it turns out to be convenient
to make their BPs in a two-stage process: to make sketchy, mostly-blank BP
structures for them early on &mdash; but getting their names registered &mdash; and
then fill in the correct details later. This is where such sketchy pairs are
made:
</p>
<pre class="display">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::make_pair_sketchily</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">f</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">relname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">relname</span><span class="plain">, </span><span class="string">"%V"</span><span class="plain">, </span><span class="identifier">WordAssemblages::first_word</span><span class="plain">(&amp;</span><span class="identifier">wa</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="functiontext">BinaryPredicates::make_pair</span><span class="plain">(</span><span class="constant">EXPLICIT_KBP</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::new_term</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">), </span><span class="functiontext">BinaryPredicates::new_term</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">),</span>
<span class="identifier">relname</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">wa</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">relname</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">f</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="element">&gt;form_of_relation</span><span class="plain"> = </span><span class="identifier">f</span><span class="plain">;</span>
<span class="reserved">return</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 BinaryPredicates::make_pair_sketchily is used in 6/rlt (<a href="6-rlt.html#SP8">&#167;8</a>).</p>
<p class="inwebparagraph"><a id="SP30"></a><b>&#167;30. BP construction. </b>The following routine should only ever be called from the two above: provided
we stick to that, we ensure the golden rule that every BP has a reversal
and a BP equals its reversal if and only if it is the equality relation}.
</p>
<p class="inwebparagraph">It looks a little asymmetric that the "make true function" schema <code class="display"><span class="extract">mtf</span></code> is an
argument here, but the "make false function" isn't. That's because it happens
that the implicit relations defined in this section of code generally do
support making-true, but don't support making-false, so that such an argument
would always be <code class="display"><span class="extract">NULL</span></code> in practice.
</p>
<pre class="display">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::make_single</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">family</span><span class="plain">,</span>
<span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">left_term</span><span class="plain">, </span><span class="reserved">bp_term_details</span><span class="plain"> </span><span class="identifier">right_term</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">,</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">mtf</span><span class="plain">, </span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">tf</span><span class="plain">, </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">rn</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">CREATE</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="element">&gt;relation_family</span><span class="plain"> = </span><span class="identifier">family</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">bp</span><span class="plain">-</span><span class="element">&gt;relation_name</span><span class="plain"> = </span><span class="identifier">rn</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">current_sentence</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;debugging_log_name</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</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">NULL</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_iname</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;handler_iname</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;v2v_bitmap_iname</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_term</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_term</span><span class="plain">;</span>
<span class="comment">the <code class="display"><span class="extract">reversal</span></code> and the <code class="display"><span class="extract">right_way_round</span></code> field must be set by the caller</span>
<span class="comment">for use in code compilation</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">NULL</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">tf</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">EMPTY_WORDING</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">mtf</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">NULL</span><span class="plain">;</span>
<span class="comment">for use by the A-parser</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;arbitrary</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;set_property</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;property_pending_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</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">FALSE</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;knowledge_about_bp</span><span class="plain"> =</span>
<span class="functiontext">InferenceSubjects::new</span><span class="plain">(</span><span class="identifier">relations</span><span class="plain">,</span>
<span class="constant">RELN_SUB</span><span class="plain">, </span><span class="identifier">STORE_POINTER_binary_predicate</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
<span class="comment">for optimisation of run-time code</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>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;initialiser_iname</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;i6_storage_property</span><span class="plain"> = </span><span class="identifier">pn</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">NULL</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;allow_function_simplification</span><span class="plain"> = </span><span class="identifier">TRUE</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">FALSE</span><span class="plain">;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;loop_parent_optimisation_proviso</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;loop_parent_optimisation_ranger</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;record_needed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="comment">details for particular kinds of relation</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;a_listed_in_predicate</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;same_property</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;comparative_property</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;comparison_sign</span><span class="plain"> = 0;</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;equivalence_partition</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">bp</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::make_single is used in <a href="#SP27">&#167;27</a>, <a href="#SP28">&#167;28</a>.</p>
<p class="inwebparagraph"><a id="SP31"></a><b>&#167;31. The package. </b></p>
<pre class="display">
<span class="identifier">package_request</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::package</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">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">"null 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;bp_package</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;bp_package</span><span class="plain"> = </span><span class="functiontext">Hierarchy::package</span><span class="plain">(</span><span class="functiontext">Modules::find</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="constant">RELATIONS_HAP</span><span class="plain">);</span>
<span class="reserved">return</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::package is used in <a href="#SP32">&#167;32</a>, <a href="#SP42">&#167;42</a>, 6/rlt (<a href="6-rlt.html#SP9">&#167;9</a>, <a href="6-rlt.html#SP9_13">&#167;9.13</a>, <a href="6-rlt.html#SP20">&#167;20</a>, <a href="6-rlt.html#SP20_3">&#167;20.3</a>).</p>
<p class="inwebparagraph"><a id="SP32"></a><b>&#167;32. The handler. </b></p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::handler_iname</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">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;handler_iname</span><span class="plain"> == </span><span class="identifier">NULL</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">bp</span><span class="plain">-</span><span class="element">&gt;handler_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">HANDLER_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;handler_iname</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::handler_iname is used in 6/rlt (<a href="6-rlt.html#SP15_2">&#167;15.2</a>, <a href="6-rlt.html#SP15_2_9_1">&#167;15.2.9.1</a>, <a href="6-rlt.html#SP15_2_10_1">&#167;15.2.10.1</a>, <a href="6-rlt.html#SP15_2_12_1">&#167;15.2.12.1</a>).</p>
<p class="inwebparagraph"><a id="SP33"></a><b>&#167;33. As an INFS. </b></p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_get_name_text</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">; </span> <span class="comment">nameless</span>
<span class="plain">}</span>
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_new_permission_granted</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_make_adj_const_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">instance</span><span class="plain"> *</span><span class="identifier">nc</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="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_complete_model</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">domain_size</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">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_bp</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">BinaryPredicates::store_dynamically</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">; </span> <span class="comment">handled at run-time instead</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">BinaryPredicates::get_form_of_relation</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">) == </span><span class="constant">Relation_Equiv</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="functiontext">Relations::equivalence_relation_make_singleton_partitions</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">domain_size</span><span class="plain">);</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">i</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">infs0</span><span class="plain">, *</span><span class="identifier">infs1</span><span class="plain">;</span>
<span class="functiontext">World::Inferences::get_references</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, &amp;</span><span class="identifier">infs0</span><span class="plain">, &amp;</span><span class="identifier">infs1</span><span class="plain">);</span>
<span class="functiontext">Relations::equivalence_relation_merge_classes</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">domain_size</span><span class="plain">,</span>
<span class="identifier">infs0</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">infs1</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Relations::equivalence_relation_add_properties</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_check_model</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="functiontext">InferenceSubjects::as_bp</span><span class="plain">(</span><span class="identifier">infs</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">) &amp;&amp;</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_OtoO</span><span class="plain">) ||</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_Sym_OtoO</span><span class="plain">)))</span>
<span class="functiontext">Relations::check_OtoO_relation</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">) &amp;&amp;</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_OtoV</span><span class="plain">) ||</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="functiontext">Relations::check_OtoV_relation</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_emit_element_of_condition</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">inter_symbol</span><span class="plain"> *</span><span class="identifier">t0_s</span><span class="plain">) {</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"BP in runtime match condition"</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>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_compile_all</span><span class="plain">(</span><span class="reserved">void</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>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::SUBJ_compile</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="functiontext">InferenceSubjects::as_bp</span><span class="plain">(</span><span class="identifier">infs</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">if</span><span class="plain"> (</span><span class="functiontext">BinaryPredicates::store_dynamically</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">bp</span><span class="plain">-</span><span class="element">&gt;initialiser_iname</span><span class="plain">);</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">rtiname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RELATIONTEST_HL</span><span class="plain">);</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">i</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">spec0</span><span class="plain">, *</span><span class="identifier">spec1</span><span class="plain">;</span>
<span class="functiontext">World::Inferences::get_references_spec</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, &amp;</span><span class="identifier">spec0</span><span class="plain">, &amp;</span><span class="identifier">spec1</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">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">rtiname</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;bp_iname</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="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec0</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">spec1</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><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;form_of_relation</span><span class="plain"> == </span><span class="constant">Relation_VtoV</span><span class="plain">) ||</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_Sym_VtoV</span><span class="plain">))</span>
<span class="functiontext">Relations::compile_vtov_storage</span><span class="plain">(</span><span class="identifier">bp</span><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 BinaryPredicates::SUBJ_get_name_text is used in 16/is (<a href="16-is.html#SP24">&#167;24</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_new_permission_granted is used in 16/is (<a href="16-is.html#SP25">&#167;25</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_make_adj_const_domain is used in 16/is (<a href="16-is.html#SP26">&#167;26</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_complete_model is used in 16/is (<a href="16-is.html#SP27">&#167;27</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_check_model is used in 16/is (<a href="16-is.html#SP28">&#167;28</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_emit_element_of_condition is used in 16/is (<a href="16-is.html#SP29">&#167;29</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_compile_all is used in 16/is (<a href="16-is.html#SP30">&#167;30</a>).</p>
<p class="endnote">The function BinaryPredicates::SUBJ_compile is used in 16/is (<a href="16-is.html#SP30">&#167;30</a>).</p>
<p class="inwebparagraph"><a id="SP34"></a><b>&#167;34. BP and term logging. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::log_term_details</span><span class="plain">(</span><span class="reserved">bp_term_details</span><span class="plain"> *</span><span class="identifier">bptd</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="identifier">LOG</span><span class="plain">(</span><span class="string">" function(%d): $i\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;function_of_other</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">bptd</span><span class="plain">-</span><span class="element">&gt;called_name</span><span class="plain">)) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">" term %d is '%W'\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;called_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_infs</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="functiontext">InferenceSubjects::get_name_text</span><span class="plain">(</span><span class="identifier">bptd</span><span class="plain">-</span><span class="element">&gt;implies_infs</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">W</span><span class="plain">)) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">" term %d has domain %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::log</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">i</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">LOG</span><span class="plain">(</span><span class="string">"&lt;null-BP&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"BP%d &lt;%S&gt; - %s way round - %s\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">bp</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;debugging_log_name</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="string">"right"</span><span class="plain">:</span><span class="string">"wrong"</span><span class="plain">,</span>
<span class="functiontext">BinaryPredicates::form_to_text</span><span class="plain">(</span><span class="identifier">bp</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;2; </span><span class="identifier">i</span><span class="plain">++) </span><span class="functiontext">BinaryPredicates::log_term_details</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">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" test: $i\</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="element">&gt;test_function</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" make true: $i\</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="element">&gt;make_true_function</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" make false: $i\</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="element">&gt;make_false_function</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" storage property: $Y\</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="element">&gt;i6_storage_property</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::log_term_details appears nowhere else.</p>
<p class="endnote">The function BinaryPredicates::log is used in 1/cm (<a href="1-cm.html#SP5">&#167;5</a>, <a href="1-cm.html#SP6_6">&#167;6.6</a>).</p>
<p class="inwebparagraph"><a id="SP35"></a><b>&#167;35. Relation names. </b>A useful little nonterminal to spot the names of relation, such as
"adjacency". (Note: not "adjacency relation".) This is only used when there
is good reason to suspect that the word in question is the name of a relation,
so the fact that it runs relatively slowly does not matter.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">relation</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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">WordAssemblages::compare_with_wording</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">W</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">bp</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">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="inwebparagraph"><a id="SP36"></a><b>&#167;36. </b></p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_log_name</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">return</span><span class="plain"> </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;debugging_log_name</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::get_log_name is used in 6/rlt (<a href="6-rlt.html#SP15_1_5">&#167;15.1.5</a>, <a href="6-rlt.html#SP29">&#167;29</a>), 9/rpt (<a href="9-rpt.html#SP9_5_1">&#167;9.5.1</a>), 11/ap (<a href="11-ap.html#SP25_2">&#167;25.2</a>), 16/is (<a href="16-is.html#SP22">&#167;22</a>).</p>
<p class="inwebparagraph"><a id="SP37"></a><b>&#167;37. Miscellaneous access routines. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::get_form_of_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">return</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::is_explicit_with_runtime_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">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">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="reserved">return</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">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="reserved">return</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="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::form_to_text</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">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_Implicit</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"Relation_Implicit"</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">return</span><span class="plain"> </span><span class="string">"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">return</span><span class="plain"> </span><span class="string">"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">return</span><span class="plain"> </span><span class="string">"Relation_VtoO"</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">return</span><span class="plain"> </span><span class="string">"Relation_VtoV"</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">return</span><span class="plain"> </span><span class="string">"Relation_Sym_OtoO"</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="reserved">return</span><span class="plain"> </span><span class="string">"Relation_Sym_VtoV"</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="reserved">return</span><span class="plain"> </span><span class="string">"Relation_Equiv"</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">return</span><span class="plain"> </span><span class="string">"Relation_ByRoutine"</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"formless-BP"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_bp_created_at</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">return</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::get_form_of_relation is used in <a href="#SP33">&#167;33</a>, 6/er (<a href="6-er.html#SP3">&#167;3</a>, <a href="6-er.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function BinaryPredicates::is_explicit_with_runtime_storage is used in 6/er (<a href="6-er.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function BinaryPredicates::form_to_text is used in <a href="#SP34">&#167;34</a>.</p>
<p class="endnote">The function BinaryPredicates::get_bp_created_at appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP38"></a><b>&#167;38. </b>Details of the terms:
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::term_kind</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">t</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">internal_error</span><span class="plain">(</span><span class="string">"tried to find kind of null relation"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::kind_of_term</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">[</span><span class="identifier">t</span><span class="plain">]));</span>
<span class="plain">}</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_term_as_function_of_other</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">t</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">internal_error</span><span class="plain">(</span><span class="string">"tried to find function of null relation"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;term_details</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">]</span><span class="element">.function_of_other</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::term_kind is used in <a href="#SP47">&#167;47</a>, 6/rlt (<a href="6-rlt.html#SP15_2_9_1">&#167;15.2.9.1</a>, <a href="6-rlt.html#SP15_2_10_1">&#167;15.2.10.1</a>, <a href="6-rlt.html#SP15_2_12_1">&#167;15.2.12.1</a>, <a href="6-rlt.html#SP20_2">&#167;20.2</a>, <a href="6-rlt.html#SP20_3">&#167;20.3</a>, <a href="6-rlt.html#SP20_4">&#167;20.4</a>, <a href="6-rlt.html#SP26">&#167;26</a>), 9/tc (<a href="9-tc.html#SP1_2_2">&#167;1.2.2</a>), 11/sc (<a href="11-sc.html#SP1_8">&#167;1.8</a>), 11/sm (<a href="11-sm.html#SP3_2">&#167;3.2</a>, <a href="11-sm.html#SP8">&#167;8</a>, <a href="11-sm.html#SP15">&#167;15</a>), 11/tcp (<a href="11-tcp.html#SP9">&#167;9</a>, <a href="11-tcp.html#SP11_1">&#167;11.1</a>), 12/ap (<a href="12-ap.html#SP9_11">&#167;9.11</a>).</p>
<p class="endnote">The function BinaryPredicates::get_term_as_function_of_other is used in 6/rlt (<a href="6-rlt.html#SP15_2_4">&#167;15.2.4</a>), 11/tr (<a href="11-tr.html#SP10">&#167;10</a>, <a href="11-tr.html#SP11">&#167;11</a>), 11/sm (<a href="11-sm.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP39"></a><b>&#167;39. </b>Reversing:
</p>
<pre class="display">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_reversal</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">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">"tried to find reversal of null relation"</span><span class="plain">);</span>
<span class="reserved">return</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::is_the_wrong_way_round</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">if</span><span class="plain"> ((</span><span class="identifier">bp</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">FALSE</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 BinaryPredicates::get_reversal is used in 6/nv (<a href="6-nv.html#SP9">&#167;9</a>), 9/rpt (<a href="9-rpt.html#SP9_5">&#167;9.5</a>), 9/tc (<a href="9-tc.html#SP1_2_2">&#167;1.2.2</a>, <a href="9-tc.html#SP8">&#167;8</a>), 9/rk (<a href="9-rk.html#SP1_1">&#167;1.1</a>, <a href="9-rk.html#SP3">&#167;3</a>), 11/sc (<a href="11-sc.html#SP1_13_1">&#167;1.13.1</a>), 11/sm (<a href="11-sm.html#SP11">&#167;11</a>), 15/vp (<a href="15-vp.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function BinaryPredicates::is_the_wrong_way_round is used in 9/tc (<a href="9-tc.html#SP8">&#167;8</a>), 9/rk (<a href="9-rk.html#SP3">&#167;3</a>), 11/sm (<a href="11-sm.html#SP11">&#167;11</a>), 11/tcp (<a href="11-tcp.html#SP6_7">&#167;6.7</a>).</p>
<p class="inwebparagraph"><a id="SP40"></a><b>&#167;40. </b>For compiling code from conditions:
</p>
<pre class="display">
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_test_function</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">return</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::can_be_made_true_at_runtime</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">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="plain">(</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;reversal</span><span class="plain">-</span><span class="element">&gt;make_true_function</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 BinaryPredicates::get_test_function appears nowhere else.</p>
<p class="endnote">The function BinaryPredicates::can_be_made_true_at_runtime is used in 6/rlt (<a href="6-rlt.html#SP15_1_2">&#167;15.1.2</a>, <a href="6-rlt.html#SP15_2">&#167;15.2</a>), 6/er (<a href="6-er.html#SP3_1">&#167;3.1</a>).</p>
<p class="inwebparagraph"><a id="SP41"></a><b>&#167;41. </b>For the A-parser. The real code is all elsewhere; note that the
<code class="display"><span class="extract">assertions</span></code> field, which is used only for relations between values rather
than objects, is a linked list. (Information about objects is stored in
linked lists pointed to from the <code class="display"><span class="extract">instance</span></code> structure in question; that
can't be done if an assertion is about values, so they are stored under the
relation itself.)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::allow_arbitrary_assertions</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">return</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::store_dynamically</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">return</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::relates_values_not_objects</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">return</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="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::as_subject</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">return</span><span class="plain"> </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;knowledge_about_bp</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::allow_arbitrary_assertions is used in 6/er (<a href="6-er.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function BinaryPredicates::store_dynamically is used in <a href="#SP33">&#167;33</a>, 6/er (<a href="6-er.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function BinaryPredicates::relates_values_not_objects is used in 9/ma (<a href="9-ma.html#SP3_3_34_3">&#167;3.3.34.3</a>), 9/rk (<a href="9-rk.html#SP3_2">&#167;3.2</a>).</p>
<p class="endnote">The function BinaryPredicates::as_subject is used in <a href="#SP33">&#167;33</a>, 6/rlt (<a href="6-rlt.html#SP20_5_1">&#167;20.5.1</a>, <a href="6-rlt.html#SP28">&#167;28</a>), 16/in (<a href="16-in.html#SP9">&#167;9</a>).</p>
<p class="inwebparagraph"><a id="SP42"></a><b>&#167;42. </b>For use when optimising code.
</p>
<pre class="display">
<span class="reserved">property</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_i6_storage_property</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">return</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::allows_function_simplification</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">return</span><span class="plain"> </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;allow_function_simplification</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">default_rr</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">BinaryPredicates::mark_as_needed</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">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">FALSE</span><span class="plain">) {</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">RELATION_RECORD_HL</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="reserved">if</span><span class="plain"> (</span><span class="identifier">default_rr</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">default_rr</span><span class="plain"> = </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_iname</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">MEANINGLESS_RR_HL</span><span class="plain">);</span>
<span class="functiontext">Emit::named_iname_constant</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">default_rr</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>
<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">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::iname</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">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="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;bp_iname</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::get_i6_storage_property is used in 6/rlt (<a href="6-rlt.html#SP28">&#167;28</a>), 6/er (<a href="6-er.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function BinaryPredicates::allows_function_simplification is used in 11/sm (<a href="11-sm.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function BinaryPredicates::mark_as_needed is used in <a href="#SP33">&#167;33</a>, 6/rlt (<a href="6-rlt.html#SP9">&#167;9</a>, <a href="6-rlt.html#SP9_9">&#167;9.9</a>, <a href="6-rlt.html#SP9_11">&#167;9.11</a>), 6/nv (<a href="6-nv.html#SP18_1">&#167;18.1</a>, <a href="6-nv.html#SP18_2">&#167;18.2</a>), 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>).</p>
<p class="endnote">The function BinaryPredicates::iname is used in 6/rlt (<a href="6-rlt.html#SP9_9">&#167;9.9</a>, <a href="6-rlt.html#SP9_11">&#167;9.11</a>, <a href="6-rlt.html#SP9_15">&#167;9.15</a>, <a href="6-rlt.html#SP15">&#167;15</a>, <a href="6-rlt.html#SP15_1">&#167;15.1</a>, <a href="6-rlt.html#SP15_2_1">&#167;15.2.1</a>, <a href="6-rlt.html#SP17">&#167;17</a>), 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>).</p>
<p class="inwebparagraph"><a id="SP43"></a><b>&#167;43. </b>For use with comparative relations.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::set_comparison_details</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">sign</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">bp</span><span class="plain">-</span><span class="element">&gt;comparison_sign</span><span class="plain"> = </span><span class="identifier">sign</span><span class="plain">; </span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;comparative_property</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::set_comparison_details is used in 15/ma (<a href="15-ma.html#SP14_2">&#167;14.2</a>).</p>
<p class="inwebparagraph"><a id="SP44"></a><b>&#167;44. </b>The predicate-calculus engine compiles much better loops if
we can help it by providing an I6 schema of a loop header solving the
following problem:
</p>
<p class="inwebparagraph">Loop a variable v (in the schema, <code class="display"><span class="extract">*1</span></code>) over all possible x such that
R(x, t), for some fixed t (in the schema, <code class="display"><span class="extract">*1</span></code>).
</p>
<p class="inwebparagraph">If we can't do this, it will still manage, but by the brute force method
of looping over all x in the left domain of R and testing every possible
R(x, t).
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::write_optimised_loop_schema</span><span class="plain">(</span><span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">sch</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">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="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Try loop ranger optimisation</span> <span class="cwebmacronumber">44.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Try loop parent optimisation subject to a proviso</span> <span class="cwebmacronumber">44.2</span>&gt;<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 BinaryPredicates::write_optimised_loop_schema is used in 12/cdp (<a href="12-cdp.html#SP5_1_1_1">&#167;5.1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP44_1"></a><b>&#167;44.1. </b>Some relations R provide a "ranger" routine, <code class="display"><span class="extract">R</span></code>, which is such that
<code class="display"><span class="extract">R(t)</span></code> supplies the first "child" of t and <code class="display"><span class="extract">R(t, n)</span></code> supplies the next
"child" after n. Thus <code class="display"><span class="extract">R</span></code> iterates through some linked list of all the
objects x such that R(x, t).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Try loop ranger optimisation</span> <span class="cwebmacronumber">44.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;loop_parent_optimisation_ranger</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Schemas::modify</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">,</span>
<span class="string">"for (*1=%s(*2): *1: *1=%s(*2,*1))"</span><span class="plain">,</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;loop_parent_optimisation_ranger</span><span class="plain">,</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;loop_parent_optimisation_ranger</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP44">&#167;44</a>.</p>
<p class="inwebparagraph"><a id="SP44_2"></a><b>&#167;44.2. </b>Other relations make use of the I6 object tree, in cases where R(x, t)
is true if and only if t is an object which is the parent of x in the
I6 object tree and some routine associated with R, called its
proviso <code class="display"><span class="extract">P</span></code>, is such that <code class="display"><span class="extract">P(x) == t</span></code>. For example, worn-by(x, t)
is true iff t is the parent of x and <code class="display"><span class="extract">WearerOf(x) == t</span></code>. The proviso
ensures that we don't falsely pick up, say, items carried by t which
aren't being worn, or aren't even clothing.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Try loop parent optimisation subject to a proviso</span> <span class="cwebmacronumber">44.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;loop_parent_optimisation_proviso</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Schemas::modify</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">,</span>
<span class="string">"objectloop (*1 in *2) if (%s(*1)==parent(*1))"</span><span class="plain">,</span>
<span class="identifier">bp</span><span class="plain">-</span><span class="element">&gt;loop_parent_optimisation_proviso</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP44">&#167;44</a>.</p>
<p class="inwebparagraph"><a id="SP45"></a><b>&#167;45. The built-in BPs. </b>Here we create spatial relationships, numerical comparisons and a few others:
all of the BPs in the "exceptional one-off cases" part of the classification
above. This happens very early in compilation.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::make_built_in</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Equality::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Properties::ProvisionRelation::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Relations::Universal::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Calculus::QuasinumericRelations::REL_create_initial_stock</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="identifier">PL::SpatialRelations::REL_create_initial_stock</span><span class="plain">();</span>
<span class="identifier">PL::MapDirections::REL_create_initial_stock</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="functiontext">Properties::SettingRelations::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Properties::SameRelations::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Properties::ComparativeRelations::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Tables::Relations::REL_create_initial_stock</span><span class="plain">();</span>
<span class="functiontext">Relations::Explicit::REL_create_initial_stock</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::make_built_in is used in 1/mr (<a href="1-mr.html#SP4_10">&#167;4.10</a>).</p>
<p class="inwebparagraph"><a id="SP46"></a><b>&#167;46. Other property-based relations. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::make_built_in_further</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Equality::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Properties::ProvisionRelation::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Relations::Universal::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Calculus::QuasinumericRelations::REL_create_second_stock</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="identifier">PL::SpatialRelations::REL_create_second_stock</span><span class="plain">();</span>
<span class="identifier">PL::MapDirections::REL_create_second_stock</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="functiontext">Properties::SettingRelations::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Properties::SameRelations::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Properties::ComparativeRelations::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Tables::Relations::REL_create_second_stock</span><span class="plain">();</span>
<span class="functiontext">Relations::Explicit::REL_create_second_stock</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::make_built_in_further is used in 1/mr (<a href="1-mr.html#SP4_12">&#167;4.12</a>).</p>
<p class="inwebparagraph"><a id="SP47"></a><b>&#167;47. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">DECLINE_TO_MATCH</span><span class="plain"> 1000 </span> <span class="comment">not one of the three legal <code class="display"><span class="extract">*_MATCH</span></code> values</span>
<span class="definitionkeyword">define</span> <span class="constant">NEVER_MATCH_SAYING_WHY_NOT</span><span class="plain"> 1001 </span> <span class="comment">not one of the three legal <code class="display"><span class="extract">*_MATCH</span></code> values</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::typecheck</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">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="reserved">tc_problem_kit</span><span class="plain"> *</span><span class="identifier">tck</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">result</span><span class="plain"> = </span><span class="constant">DECLINE_TO_MATCH</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">result</span><span class="plain"> = </span><span class="functiontext">Calculus::Equality::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">result</span><span class="plain"> = </span><span class="functiontext">Properties::ProvisionRelation::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">UNIVERSAL_KBP</span><span class="plain">: </span><span class="identifier">result</span><span class="plain"> = </span><span class="functiontext">Relations::Universal::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">result</span><span class="plain"> = </span><span class="functiontext">Calculus::QuasinumericRelations::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</span><span class="plain">); </span><span class="reserved">break</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">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">result</span><span class="plain"> = </span><span class="identifier">PL::SpatialRelations::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">result</span><span class="plain"> = </span><span class="identifier">PL::MapDirections::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">result</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">MAP_CONNECTING_KBP</span><span class="plain">: </span><span class="identifier">result</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="plain">#</span><span class="identifier">endif</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROPERTY_SETTING_KBP</span><span class="plain">: </span><span class="identifier">result</span><span class="plain"> = </span><span class="functiontext">Properties::SettingRelations::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">PROPERTY_SAME_KBP</span><span class="plain">: </span><span class="identifier">result</span><span class="plain"> = </span><span class="functiontext">Properties::SameRelations::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">PROPERTY_COMPARISON_KBP</span><span class="plain">: </span><span class="identifier">result</span><span class="plain"> = </span><span class="functiontext">Properties::ComparativeRelations::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">LISTED_IN_KBP</span><span class="plain">: </span><span class="identifier">result</span><span class="plain"> = </span><span class="functiontext">Tables::Relations::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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="identifier">result</span><span class="plain"> = </span><span class="functiontext">Relations::Explicit::REL_typecheck</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">kinds_of_terms</span><span class="plain">, </span><span class="identifier">kinds_required</span><span class="plain">, </span><span class="identifier">tck</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">"typechecked unknown KBP"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">result</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::assert</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">inference_subject</span><span class="plain"> *</span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec0</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec1</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">success</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">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">success</span><span class="plain"> = </span><span class="functiontext">Calculus::Equality::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">success</span><span class="plain"> = </span><span class="functiontext">Properties::ProvisionRelation::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">UNIVERSAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Relations::Universal::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">success</span><span class="plain"> = </span><span class="functiontext">Calculus::QuasinumericRelations::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</span><span class="plain">); </span><span class="reserved">break</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">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">PL::SpatialRelations::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">success</span><span class="plain"> = </span><span class="identifier">PL::MapDirections::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">FALSE</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">success</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROPERTY_SETTING_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::SettingRelations::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">PROPERTY_SAME_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::SameRelations::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">PROPERTY_COMPARISON_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::ComparativeRelations::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">LISTED_IN_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Tables::Relations::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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="identifier">success</span><span class="plain"> = </span><span class="functiontext">Relations::Explicit::REL_assert</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">subj0</span><span class="plain">, </span><span class="identifier">spec0</span><span class="plain">, </span><span class="identifier">subj1</span><span class="plain">, </span><span class="identifier">spec1</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">"asserted unknown KBP"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">success</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="functiontext">BinaryPredicates::get_i6_schema</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="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</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">int</span><span class="plain"> </span><span class="identifier">success</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">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">success</span><span class="plain"> = </span><span class="functiontext">Calculus::Equality::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">success</span><span class="plain"> = </span><span class="functiontext">Properties::ProvisionRelation::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">UNIVERSAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Relations::Universal::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">success</span><span class="plain"> = </span><span class="functiontext">Calculus::QuasinumericRelations::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</span><span class="plain">); </span><span class="reserved">break</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">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">PL::SpatialRelations::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">success</span><span class="plain"> = </span><span class="identifier">PL::MapDirections::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">FALSE</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">success</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROPERTY_SETTING_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::SettingRelations::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">PROPERTY_SAME_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::SameRelations::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">PROPERTY_COMPARISON_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::ComparativeRelations::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">LISTED_IN_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Tables::Relations::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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="identifier">success</span><span class="plain"> = </span><span class="functiontext">Relations::Explicit::REL_compile</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">asch</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">"compiled unknown KBP"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">success</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">task</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TEST_ATOM_TASK</span><span class="plain">: </span><span class="identifier">asch</span><span class="plain">-</span><span class="element">&gt;schema</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NOW_ATOM_TRUE_TASK</span><span class="plain">: </span><span class="identifier">asch</span><span class="plain">-</span><span class="element">&gt;schema</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NOW_ATOM_FALSE_TASK</span><span class="plain">: </span><span class="identifier">asch</span><span class="plain">-</span><span class="element">&gt;schema</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="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">asch</span><span class="plain">-</span><span class="element">&gt;schema</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::describe_for_problems</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="reserved">int</span><span class="plain"> </span><span class="identifier">success</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">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">success</span><span class="plain"> = </span><span class="functiontext">Calculus::Equality::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">success</span><span class="plain"> = </span><span class="functiontext">Properties::ProvisionRelation::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">UNIVERSAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Relations::Universal::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">success</span><span class="plain"> = </span><span class="functiontext">Calculus::QuasinumericRelations::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">); </span><span class="reserved">break</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">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">PL::SpatialRelations::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">success</span><span class="plain"> = </span><span class="identifier">PL::MapDirections::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SPATIAL_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">FALSE</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">success</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROPERTY_SETTING_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::SettingRelations::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">PROPERTY_SAME_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::SameRelations::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">PROPERTY_COMPARISON_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Properties::ComparativeRelations::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">LISTED_IN_KBP</span><span class="plain">: </span><span class="identifier">success</span><span class="plain"> = </span><span class="functiontext">Tables::Relations::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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="identifier">success</span><span class="plain"> = </span><span class="functiontext">Relations::Explicit::REL_describe_for_problems</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">bp</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">"found unknown KBP"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">success</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</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">success</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">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">WRITE</span><span class="plain">(</span><span class="string">"the %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="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" relation"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K0</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="reserved">if</span><span class="plain"> (</span><span class="identifier">K0</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K0</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K1</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">K1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K1</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (between "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K0</span><span class="plain">, </span><span class="identifier">K1</span><span class="plain">)) {</span>
<span class="identifier">Kinds::Textual::write_plural</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">K0</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Kinds::Textual::write_articled</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">K0</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" and "</span><span class="plain">);</span>
<span class="identifier">Kinds::Textual::write_articled</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">K1</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">")"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::typecheck is used in 11/tcp (<a href="11-tcp.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function BinaryPredicates::assert is used in 12/ap (<a href="12-ap.html#SP9_11">&#167;9.11</a>).</p>
<p class="endnote">The function BinaryPredicates::get_i6_schema is used in 6/rlt (<a href="6-rlt.html#SP15_2_2">&#167;15.2.2</a>, <a href="6-rlt.html#SP15_2_3">&#167;15.2.3</a>, <a href="6-rlt.html#SP15_2_4">&#167;15.2.4</a>), 12/ca (<a href="12-ca.html#SP6_7">&#167;6.7</a>).</p>
<p class="endnote">The function BinaryPredicates::describe_for_problems is used in 2/sq (<a href="2-sq.html#SP1">&#167;1</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 6: Verbs.)</i></li><li><a href="6-rlt.html">Continue with 'Relations'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>