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

1393 lines
177 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>20/eq</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 '21/rl' 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#21">Chapter 21: Rules and Rulebooks</a></li><li><b>Rules</b></li></ul><p class="purpose">Rule structures abstract the Inform 7 concept of a rule, which may be defined either by an Inform 6 routine or by higher-level source text from a phrase structure.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP5">&#167;5. The rule structure</a></li><li><a href="#SP8">&#167;8. The kind of a rule</a></li><li><a href="#SP9">&#167;9. Definitions</a></li><li><a href="#SP10">&#167;10. Applicability constraints</a></li><li><a href="#SP12">&#167;12. Logging</a></li><li><a href="#SP13">&#167;13. Specificity of rules</a></li><li><a href="#SP15">&#167;15. As constant values</a></li><li><a href="#SP16">&#167;16. Variables accessible from here</a></li><li><a href="#SP17">&#167;17. Automatic placement into rulebooks</a></li><li><a href="#SP18">&#167;18. Check safety of placement constraints</a></li><li><a href="#SP19">&#167;19. Run-time representation</a></li><li><a href="#SP20">&#167;20. Printing rule names at run time</a></li><li><a href="#SP22">&#167;22. Compilation</a></li><li><a href="#SP23">&#167;23. Indexing</a></li><li><a href="#SP26">&#167;26. Actor testing</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>Rules are not the same thing as phrases. While most do have phrase-like
definitions,
</p>
<blockquote>
<p>Before eating: say "The candlelight flickers ominously."</p>
</blockquote>
<p class="inwebparagraph">they do not provide new syntax for the writing of other phrases; they are
often nameless, as in this example; and they are sometimes defined not by
an I7 <code class="display"><span class="extract">phrase</span></code> structure but by an I6 routine:
</p>
<blockquote>
<p>The can't reach inside rooms rule translates into I6 as |"CANT_REACH_INSIDE_ROOMS_R"|.</p>
</blockquote>
<p class="inwebparagraph">Note that:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) There is only one rule with any given name, except that there can be any
number of rules which are nameless. Rule names do not need to end in
"...rule", and though most do, rules for timed events do not.
</li></ul>
<ul class="items"><li>(b) Any given rule must have a "definition" which is either an I7 <code class="display"><span class="extract">phrase</span></code>
arising from source text, or an I6 routine named in quotation marks. If the
latter, then Inform simply assumes this routine has been provided, either
by the I6 template or by an insertion.
</li></ul>
<ul class="items"><li>(c) Conditions for the rule to apply &mdash; for instance, that the action has to
be "eating" &mdash; are stored in the <code class="display"><span class="extract">phrase</span></code> structure, not here. It follows
that an I6 routine-defined rule is used unconditionally: the expectation is
that the routine will decline to act if the situation isn't to its liking.
</li></ul>
<ul class="items"><li>(d) However, the same is not true of "applicability conditions", for which
see below.
</li></ul>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rule</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">name</span><span class="plain">; </span> <span class="comment">name of the rule being booked</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">explicitly_named</span><span class="plain">; </span> <span class="comment">was this rule explicitly named when created?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">italicised_text</span><span class="plain">; </span> <span class="comment">when indexing a rulebook</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">stacked_variable_owner_list</span><span class="plain"> *</span><span class="identifier">listed_stv_owners</span><span class="plain">; </span> <span class="comment">making vars visible here</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">defn_as_phrase</span><span class="plain">; </span> <span class="comment">the rule being booked</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">rule_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">shell_routine_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">rule_extern_iname</span><span class="plain">; </span> <span class="comment">if externally defined, this is the I6 routine</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">rule_extern_iname_as_text</span><span class="plain">; </span> <span class="comment">and this is it in plain text</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">xiname</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">rule_extern_response_handler_iname</span><span class="plain">; </span> <span class="comment">and this produces any response texts it has</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">do_not_import</span><span class="plain">; </span> <span class="comment">veto importation of this from the Standard Rules precompiled inter code</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">defn_compiled</span><span class="plain">; </span> <span class="comment">has the definition of this rule, if needed, been compiled yet?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">automatic_booking</span><span class="plain">; </span> <span class="comment">how this is placed in rulebooks</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">first_applicability_condition</span><span class="plain">; </span> <span class="comment">see below</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">response_message</span><span class="plain"> *</span><span class="identifier">lettered_responses</span><span class="plain">[26]; </span> <span class="comment">responses (A), (B), ...</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">lettered_responses_used</span><span class="plain">[26]; </span> <span class="comment">responses (A), (B), ...</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_of_rule</span><span class="plain">; </span> <span class="comment">determined from its rulebook(s)</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">kind_of_rule_set_from</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">lettered_responses_value</span><span class="plain">[26];</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">rule</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure rule is accessed in 2/sq, 2/si, 5/ins, 5/nv, 8/ed2, 9/ma, 9/pk, 11/sm, 14/lv, 14/ds2, 15/pr, 15/ep, 15/vp, 15/spr, 16/in, 16/cmw, 17/rs, 19/tc, 19/tb, 19/tod, 20/eq, 21/rl2, 21/fao, 21/rps, 21/sv, 21/ac, 22/pu, 22/prcd, 22/dptd, 22/po, 22/pav, 25/cii, 26/uo, 26/ts and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">rule_being_compiled</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">rule whose phrase's definition is being compiled</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">adopted_rule_for_compilation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">when a new response is being compiled</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">adopted_marker_for_compilation</span><span class="plain"> = -1; </span> <span class="comment">when a new response is being compiled</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Applicability conditions are a way to control the behaviour of rules written
in somebody else's source text: for example, in the Standard Rules, or in an
extension. They were introduced to the language in January 2011 to replace
the functionality previously provided by procedural rules. For example,
</p>
<blockquote>
<p>The can't reach inside rooms rule does nothing if the player wears the black hat.</p>
</blockquote>
<p class="inwebparagraph">We can either cancel the rule ("does nothing") or substitute another rule
for it, and this can be either conditional or unconditional. There can be any
number of conditions attached to a given rule, so these are stored in a list.
</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">applicability_condition</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">text_of_condition</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense_of_applicability</span><span class="plain">; </span> <span class="comment"><code class="display"><span class="extract">TRUE</span></code> if condition must hold for rule to have effect</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">substituted_rule</span><span class="plain">; </span> <span class="comment">rule to use instead if not, or <code class="display"><span class="extract">NULL</span></code> to do nothing</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">where_imposed</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">next_applicability_condition</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">applicability_condition</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure applicability_condition is private to this section.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. The rule structure. </b>Rules are created before their definitions are known. This is done so that
rules like
</p>
<blockquote>
<p>Before eating (this is the must say grace rule): ...</p>
</blockquote>
<p class="inwebparagraph">cause "must say grace rule" to be registered as a constant value early in
Inform's run (allowing it to be a property value, or a table entry, for
example). Note that the rule may just as well be nameless, as here:
</p>
<blockquote>
<p>Before drinking: ...</p>
</blockquote>
<p class="inwebparagraph">in which case <code class="display"><span class="extract">w1 == -1</span></code>. In either case, the definition should be supplied
later: see below.
</p>
<pre class="display">
<span class="reserved">rule</span><span class="plain"> *</span><span class="functiontext">Rules::new</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">named</span><span class="plain">) {</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Rules::by_name</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;xiname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_response_handler_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;italicised_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;listed_stv_owners</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;automatic_booking</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_compiled</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;do_not_import</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;explicitly_named</span><span class="plain"> = </span><span class="identifier">named</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;shell_routine_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</span><span class="plain"> = </span><span class="functiontext">Hierarchy::local_package</span><span class="plain">(</span><span class="constant">RULES_HAP</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="functiontext">Hierarchy::markup_wording</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</span><span class="plain">, </span><span class="constant">RULE_NAME_HMD</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">=0; </span><span class="identifier">l</span><span class="plain">&lt;26; </span><span class="identifier">l</span><span class="plain">++) {</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_used</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_value</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">] = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::vet_name</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Register the name of this rule</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::new is used in 21/rps (<a href="21-rps.html#SP1">&#167;1</a>), 22/pu (<a href="22-pu.html#SP5">&#167;5</a>, <a href="22-pu.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b>We make a modest speed gain by registering rule names which end in "rule"
slightly differently. (Not all rule names do: those for timed events do not.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Register the name of this rule</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">mc</span><span class="plain"> = </span><span class="constant">RULE_MC</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">formal</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">mc</span><span class="plain"> = </span><span class="identifier">MISCELLANEOUS_MC</span><span class="plain">;</span>
<span class="identifier">Nouns::new_proper_noun</span><span class="plain">(</span><span class="identifier">W</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">mc</span><span class="plain">, </span><span class="functiontext">Rvalues::from_rule</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Reversing the process:
</p>
<pre class="display">
<span class="reserved">rule</span><span class="plain"> *</span><span class="functiontext">Rules::by_name</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</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="identifier">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">formal</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">MISCELLANEOUS_MC</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">CON_rule</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_rule</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="constant">RULE_MC</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">CON_rule</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_rule</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::by_name is used in <a href="#SP5">&#167;5</a>, 21/rps (<a href="21-rps.html#SP2">&#167;2</a>), 22/pu (<a href="22-pu.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">PM_RuleWithComma_issued_at</span><span class="plain"> = -1;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::vet_name</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">unsuitable</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PM_RuleWithComma_issued_at</span><span class="plain"> != </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">PM_RuleWithComma_issued_at</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RuleWithComma</span><span class="plain">),</span>
<span class="string">"a rule name is not allowed to contain punctuation, or "</span>
<span class="string">"to consist only of an article like 'a' or 'an', or to "</span>
<span class="string">"contain double-quoted text"</span><span class="plain">,</span>
<span class="string">"because this leads to too much ambiguity later on."</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>
<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">The function Rules::vet_name is used in <a href="#SP5">&#167;5</a>, 22/pu (<a href="22-pu.html#SP10_4">&#167;10.4</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. The kind of a rule. </b>Note the convention, a historical accident, really, that a rule with no known
kind is considered to be action-based and resulting in nothing.
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Rules::to_kind</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</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">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_rule</span><span class="plain">, </span><span class="identifier">K_action_name</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">);</span>
<span class="reserved">return</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 Rules::to_kind is used in 14/rv (<a href="14-rv.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Definitions. </b>The definition of a rule can be either an I7 phrase, or an I6 routine, and
must be added after the rule has been created:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::set_I7_definition</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">) {</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::set_I6_definition</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">identifier</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">XT</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">XT</span><span class="plain">, </span><span class="string">"%w"</span><span class="plain">, </span><span class="identifier">identifier</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">EXTERIOR_RULE_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">xiname</span><span class="plain"> = </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">XT</span><span class="plain">);</span>
<span class="functiontext">Emit::named_generic_constant_xiname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">, </span><span class="identifier">xiname</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;xiname</span><span class="plain"> = </span><span class="identifier">xiname</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname_as_text</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">XT</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">XT</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Rules::get_handler_definition</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_response_handler_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_response_handler_iname</span><span class="plain"> =</span>
<span class="functiontext">Hierarchy::derive_iname_in</span><span class="plain">(</span><span class="constant">RESPONDER_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;xiname</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</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">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_response_handler_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_response_handler_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="functiontext">Rules::get_I7_definition</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::set_I7_definition is used in 22/pu (<a href="22-pu.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Rules::set_I6_definition is used in 21/rps (<a href="21-rps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Rules::get_handler_definition is used in 17/rs (<a href="17-rs.html#SP6_2">&#167;6.2</a>).</p>
<p class="endnote">The function Rules::get_I7_definition is used in 21/rb (<a href="21-rb.html#SP8">&#167;8</a>, <a href="21-rb.html#SP17">&#167;17</a>, <a href="21-rb.html#SP18">&#167;18</a>, <a href="21-rb.html#SP25">&#167;25</a>), 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>), 22/pu (<a href="22-pu.html#SP6_2">&#167;6.2</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_12">&#167;3.1.1.4.12</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Applicability constraints. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::impose_constraint</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
<span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">nac</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">applicability_condition</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Initialise the applicability condition</span> <span class="cwebmacronumber">10.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Add it to the list applying to R</span> <span class="cwebmacronumber">10.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::impose_constraint is used in 21/rps (<a href="21-rps.html#SP9">&#167;9</a>, <a href="21-rps.html#SP14">&#167;14</a>).</p>
<p class="inwebparagraph"><a id="SP10_1"></a><b>&#167;10.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Initialise the applicability condition</span> <span class="cwebmacronumber">10.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">nac</span><span class="plain">-</span><span class="element">&gt;text_of_condition</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">nac</span><span class="plain">-</span><span class="element">&gt;sense_of_applicability</span><span class="plain"> = </span><span class="identifier">sense</span><span class="plain">;</span>
<span class="identifier">nac</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nac</span><span class="plain">-</span><span class="element">&gt;where_imposed</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">nac</span><span class="plain">-</span><span class="element">&gt;substituted_rule</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP10_2"></a><b>&#167;10.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Add it to the list applying to R</span> <span class="cwebmacronumber">10.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">ac</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ac</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain"> = </span><span class="identifier">nac</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">ac</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain">))</span>
<span class="identifier">ac</span><span class="plain"> = </span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain">;</span>
<span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain"> = </span><span class="identifier">nac</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>The following generates code to terminate a rule early if its applicability
conditions have not been met.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::compile_constraint</span><span class="plain">(</span><span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">acl</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">acl</span><span class="plain">; </span><span class="identifier">acl</span><span class="plain"> = </span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain">) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;where_imposed</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">acl</span><span class="plain">-</span><span class="element">&gt;text_of_condition</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;sense_of_applicability</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="plain">}</span>
&lt;<span class="cwebmacro">Compile the constraint condition</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;sense_of_applicability</span><span class="plain">) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Compile the rule termination code used if the constraint was violated</span> <span class="cwebmacronumber">11.2</span>&gt;<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">acl</span><span class="plain">-</span><span class="element">&gt;text_of_condition</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="reserved">else</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="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 Rules::compile_constraint is used in <a href="#SP22_1">&#167;22.1</a>, 22/prcd (<a href="22-prcd.html#SP10">&#167;10</a>).</p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the constraint condition</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;text_of_condition</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">condition</span><span class="plain">&gt;(</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;text_of_condition</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="functiontext">Dash::check_condition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;text_of_condition</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadRuleConstraint</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, you placed a constraint '%2' on a rule, but this isn't "</span>
<span class="string">"a condition I can understand."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 1);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_2"></a><b>&#167;11.2. </b>Note that in the does nothing case, the rule ends without result, rather than
failing; so it doesn't terminate the following of its rulebook.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile the rule termination code used if the constraint was violated</span> <span class="cwebmacronumber">11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;substituted_rule</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">subbed</span><span class="plain"> = </span><span class="functiontext">Rules::iname</span><span class="plain">(</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;substituted_rule</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Constant::is_routine</span><span class="plain">(</span><span class="identifier">InterNames::to_symbol</span><span class="plain">(</span><span class="identifier">subbed</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="plain">} </span><span class="reserved">else</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">subbed</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Logging. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::log</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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-rule&gt;"</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">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"[$R]"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</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">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"[%n]"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</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 Rules::log is used in 17/ts (<a href="17-ts.html#SP8">&#167;8</a>), 21/rb (<a href="21-rb.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Specificity of rules. </b>The following is one of Inform's standardised comparison routines, which
takes a pair of objects A, B and returns 1 if A makes a more specific
description than B, 0 if they seem equally specific, or -1 if B makes a
more specific description than A. This is transitive, and intended to be
used in sorting algorithms.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::compare_specificity</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R1</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R2</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">dflag</span><span class="plain">) {</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph1</span><span class="plain"> = </span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">, *</span><span class="identifier">ph2</span><span class="plain"> = </span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">;</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">phrcd2</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">ph1</span><span class="plain">) </span><span class="identifier">phrcd1</span><span class="plain"> = &amp;(</span><span class="identifier">ph1</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph2</span><span class="plain">) </span><span class="identifier">phrcd2</span><span class="plain"> = &amp;(</span><span class="identifier">ph2</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Phrases::Context::compare_specificity</span><span class="plain">(</span><span class="identifier">phrcd1</span><span class="plain">, </span><span class="identifier">phrcd2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dflag</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> != 0) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Decided by Law %s that "</span><span class="plain">, </span><span class="identifier">c_s_stage_law</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Decided that "</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> -1: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(2) is more specific than (1)\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"they are equally specific\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(1) is more specific than (2)\</span><span class="plain">n</span><span class="string">"</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">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::compare_specificity is used in 21/rb (<a href="21-rb.html#SP10">&#167;10</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>It may seem unlikely, but it's possible for two rules to refer to the
same routine at runtime, if two or more I7 names have been declared which
refer to the same I6 routine. So, we have the following. (It is used only
late on in the run, and never applied to undefined rules.)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R1</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain"> != </span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</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">R1</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">) &amp;&amp; (</span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname_as_text</span><span class="plain">, </span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname_as_text</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">if</span><span class="plain"> ((</span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="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 Rules::eq is used in 21/rb (<a href="21-rb.html#SP14_2">&#167;14.2</a>, <a href="21-rb.html#SP14_3">&#167;14.3</a>, <a href="21-rb.html#SP14_6_1">&#167;14.6.1</a>, <a href="21-rb.html#SP15">&#167;15</a>, <a href="21-rb.html#SP17">&#167;17</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. As constant values. </b>An interesting point is raised here. What is the kind of a rule? Clearly
it should be a "rule", but that isn't precise. Older versions of Inform
blurred this by using the indefinite "value based rule producing a value",
but this led to a number of anomalies, such as that
</p>
<blockquote>
<p>let R be the foo rule;</p>
</blockquote>
<p class="inwebparagraph">would fail to work because the kind of "foo rule" could not be inferred
to a definite kind. What now happens is that whenever a rule is added to
a rulebook, the following is called to notify us that it provides information
about the kind of the rule; and this enables us to check for incompatibilities.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::set_kind_from</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">RB</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">Rulebooks::contains_kind</span><span class="plain">(</span><span class="identifier">RB</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::compatible</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">) != </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">B1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">B2</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">P1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">P2</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain">, &amp;</span><span class="identifier">B1</span><span class="plain">, &amp;</span><span class="identifier">P1</span><span class="plain">);</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, &amp;</span><span class="identifier">B2</span><span class="plain">, &amp;</span><span class="identifier">P2</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">B1</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">P1</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(5, </span><span class="identifier">B2</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(6, </span><span class="identifier">P2</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording_as_source</span><span class="plain">(7, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule_set_from</span><span class="plain">-</span><span class="element">&gt;primary_name</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording_as_source</span><span class="plain">(8, </span><span class="identifier">RB</span><span class="plain">-</span><span class="element">&gt;primary_name</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RuleInIncompatibleRulebooks</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You've asked to put the rule '%2' into the rulebook %8, "</span>
<span class="string">"which is based on %5 and produces %6; but it was originally "</span>
<span class="string">"written to go into a rulebook of a different kind, %7, "</span>
<span class="string">"which is based on %3 and produces %4. Because those kinds "</span>
<span class="string">"are different, '%2' can't go into %8."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule_set_from</span><span class="plain"> = </span><span class="identifier">RB</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::set_kind_from is used in 21/rb (<a href="21-rb.html#SP8">&#167;8</a>), 21/rps (<a href="21-rps.html#SP18">&#167;18</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Variables accessible from here. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::acquire_stvol</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">stacked_variable_owner_list</span><span class="plain"> *</span><span class="identifier">stvol</span><span class="plain">) {</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;listed_stv_owners</span><span class="plain"> =</span>
<span class="functiontext">StackedVariables::append_owner_list</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;listed_stv_owners</span><span class="plain">, </span><span class="identifier">stvol</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::acquire_action_variables</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</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="functiontext">Rules::acquire_stvol</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">all_nonempty_stacked_action_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">all_action_processing_vars</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">"APROC not ready"</span><span class="plain">);</span>
<span class="functiontext">Rules::acquire_stvol</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">all_action_processing_vars</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::acquire_stvol is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="endnote">The function Rules::acquire_action_variables is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Automatic placement into rulebooks. </b>Some BRs are given their placements with explicit sentences like:
</p>
<blockquote>
<p>The can't reach inside closed containers rule is listed in the reaching inside rules.</p>
</blockquote>
<p class="inwebparagraph">But others have their placements made implicitly in their definitions:
</p>
<blockquote>
<p>Before eating something: ...</p>
</blockquote>
<p class="inwebparagraph">(which creates a nameless rule and implicitly places it in the "before"
rulebook). The process of placing those is called "automatic placement".
</p>
<p class="inwebparagraph">Automatic placement occurs in declaration order. This is important, because
it ensures that it is declaration order which the rule-sorting code falls back
on when it can see no other justification for placing one rule either side
of another.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::request_automatic_placement</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;automatic_booking</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;automatic_booking</span><span class="plain"> = </span><span class="functiontext">Rules::Bookings::new</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">);</span>
<span class="functiontext">Rules::Bookings::request_automatic_placement</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;automatic_booking</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::request_automatic_placement is used in 22/ph (<a href="22-ph.html#SP6_7">&#167;6.7</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Check safety of placement constraints. </b>This is more interesting than it might seem. We allow a rule based on nothing
to substitute for a rule based on some value (or an action) because of course
it's perfectly typesafe to ignore the basis value entirely.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::check_placement_safety</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KR</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain">;</span>
<span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">ac</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">ac</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">; </span><span class="identifier">ac</span><span class="plain">; </span><span class="identifier">ac</span><span class="plain"> = </span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;substituted_rule</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KS</span><span class="plain"> = </span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;substituted_rule</span><span class="plain">-</span><span class="element">&gt;kind_of_rule</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">B1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">B2</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">P1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">P2</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">KR</span><span class="plain">, &amp;</span><span class="identifier">B1</span><span class="plain">, &amp;</span><span class="identifier">P1</span><span class="plain">);</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">KS</span><span class="plain">, &amp;</span><span class="identifier">B2</span><span class="plain">, &amp;</span><span class="identifier">P2</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">B1</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">B1</span><span class="plain"> = </span><span class="identifier">K_nil</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">B2</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">B2</span><span class="plain"> = </span><span class="identifier">K_nil</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">P1</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">P1</span><span class="plain"> = </span><span class="identifier">K_nil</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">P2</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">P2</span><span class="plain"> = </span><span class="identifier">K_nil</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">B2</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">)) </span><span class="identifier">B2</span><span class="plain"> = </span><span class="identifier">B1</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="identifier">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_rule</span><span class="plain">, </span><span class="identifier">B1</span><span class="plain">, </span><span class="identifier">P1</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K2</span><span class="plain"> = </span><span class="identifier">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_rule</span><span class="plain">, </span><span class="identifier">B2</span><span class="plain">, </span><span class="identifier">P2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::compatible</span><span class="plain">(</span><span class="identifier">K2</span><span class="plain">, </span><span class="identifier">K1</span><span class="plain">) != </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;where_imposed</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ac</span><span class="plain">-</span><span class="element">&gt;substituted_rule</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">KR</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(5, </span><span class="identifier">KS</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RulesCantInterchange</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the sentence %1 you've asked to use the rule '%2' in "</span>
<span class="string">"place of '%3', but one is based on %4 whereas the other "</span>
<span class="string">"is %5, and those aren't interchangeable."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</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 Rules::check_placement_safety is used in 21/rl2 (<a href="21-rl2.html#SP20">&#167;20</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Run-time representation. </b>In I6 code, a rule is compiled to the name of the routine implementing it,
an I6 value of metaclass <code class="display"><span class="extract">Routine</span></code>. See compilation below for what rule shells
do.
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Rules::shell_iname</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;shell_routine_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;shell_routine_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">SHELL_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;shell_routine_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Rules::iname</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Phrases::iname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</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">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rules::shell_iname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to symbolise nameless rule"</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::shell_iname is used in <a href="#SP22_1">&#167;22.1</a>.</p>
<p class="endnote">The function Rules::iname is used in <a href="#SP11_2">&#167;11.2</a>, <a href="#SP20_2">&#167;20.2</a>, <a href="#SP20_2_1">&#167;20.2.1</a>, 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>), 17/rs (<a href="17-rs.html#SP7_2">&#167;7.2</a>), 27/ei (<a href="27-ei.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. Printing rule names at run time. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::RulePrintingRule_routine</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RULEPRINTINGRULE_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">R_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"R"</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">GE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">NUMBER_RULEBOOKS_CREATED_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">Print a rulebook name</span> <span class="cwebmacronumber">20.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">Print a rule name</span> <span class="cwebmacronumber">20.2</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::RulePrintingRule_routine is used in 22/cs (<a href="22-cs.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP20_1"></a><b>&#167;20.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Print a rulebook name</span> <span class="cwebmacronumber">20.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">memory_economy_in_force</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">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"(rulebook "</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">")"</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTSTRING_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">LOOKUP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RULEBOOKNAMES_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP20_2"></a><b>&#167;20.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Print a rule name</span> <span class="cwebmacronumber">20.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">memory_economy_in_force</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">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"(rule at address "</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">")"</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rule</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">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)))</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Rules::iname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Print a textual name for this rule</span> <span class="cwebmacronumber">20.2.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"(nameless rule at address "</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_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_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">")"</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP20_2_1"></a><b>&#167;20.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Print a textual name for this rule</span> <span class="cwebmacronumber">20.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">)) {</span>
<span class="functiontext">CompiledText::from_text</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</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">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">) {</span>
<span class="functiontext">CompiledText::from_text</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
<span class="identifier">Articles::remove_the</span><span class="plain">(</span>
<span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">)));</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">"%n"</span><span class="plain">, </span><span class="functiontext">Rules::iname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20_2">&#167;20.2</a>.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::compile_comment</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">index</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"Rule %d/%d"</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">": %n"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::comment</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) {</span>
<span class="functiontext">Phrases::Usage::write_I6_comment_describing</span><span class="plain">(&amp;(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;usage_data</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::compile_comment is used in 21/rb (<a href="21-rb.html#SP22">&#167;22</a>).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. Compilation. </b>Only those rules defined as I7 phrases need us to compile anything &mdash; and then
what we compile, of course, is the phrase in question.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::compile_definition</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">i</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">max_i</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_compiled</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_compiled</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">rule_being_compiled</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">)</span>
<span class="functiontext">Phrases::compile</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">max_i</span><span class="plain">,</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;listed_stv_owners</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">) &amp;&amp; (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Compile a shell routine to apply conditions to an I6 rule</span> <span class="cwebmacronumber">22.1</span>&gt;<span class="plain">;</span>
<span class="identifier">rule_being_compiled</span><span class="plain"> = </span><span class="identifier">NULL</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">Rules::unimport</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_compiled</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;do_not_import</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">R</span><span class="plain">-</span><span class="element">&gt;defn_compiled</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;do_not_import</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;imported</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 Rules::compile_definition is used in 22/cs (<a href="22-cs.html#SP10_3">&#167;10.3</a>, <a href="22-cs.html#SP14">&#167;14</a>).</p>
<p class="endnote">The function Rules::unimport is used in <a href="#SP26">&#167;26</a>.</p>
<p class="inwebparagraph"><a id="SP22_1"></a><b>&#167;22.1. </b>This is the trickiest case: where the user has asked for something like
</p>
<blockquote>
<p>The carrying requirements rule does nothing when eating the lollipop.</p>
</blockquote>
<p class="inwebparagraph">and the carrying requirements rule is defined by an I6 routine, which we
are unable to modify. What we do is to create a shell routine to call it,
and put the conditions into this outer shell; we then use the outer shell
as the definition of the rule in future.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a shell routine to apply conditions to an I6 rule</span> <span class="cwebmacronumber">22.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">shell_iname</span><span class="plain"> = </span><span class="functiontext">Rules::shell_iname</span><span class="plain">(</span><span class="identifier">R</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">shell_iname</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::compile_constraint</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Indexing. </b>Some rules are provided with index text:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::set_italicised_index_text</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</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">R</span><span class="plain">-</span><span class="element">&gt;italicised_text</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::set_italicised_index_text is used in 22/pu (<a href="22-pu.html#SP6_3">&#167;6.3</a>).</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>A use option controls whether little rule numbers are shown in the index.
I wonder how useful this really is, but it was much requested at one time.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">use_numbered_rules</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::set_numbered_rules</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">use_numbered_rules</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">The function Rules::set_numbered_rules is used in 26/uo (<a href="26-uo.html#SP13_1">&#167;13.1</a>).</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>And off we go:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain">, </span><span class="reserved">rule_context</span><span class="plain"> </span><span class="identifier">rc</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_responses_indexed</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;italicised_text</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Index the italicised text to do with the rule</span> <span class="cwebmacronumber">25.1</span>&gt;<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">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Index the rule name along with Javascript buttons</span> <span class="cwebmacronumber">25.2</span>&gt;<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">R</span><span class="plain">-</span><span class="element">&gt;italicised_text</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Index some text extracted from the first line of the otherwise anonymous rule</span> <span class="cwebmacronumber">25.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Index a link to the first line of the rule's definition</span> <span class="cwebmacronumber">25.5</span>&gt;<span class="character">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_numbered_rules</span><span class="plain">) </span>&lt;<span class="cwebmacro">Index the small type rule numbering</span> <span class="cwebmacronumber">25.6</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Index any applicability conditions</span> <span class="cwebmacronumber">25.7</span>&gt;<span class="plain">;</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Index any response texts in the rule</span> <span class="cwebmacronumber">25.3</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">no_responses_indexed</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::index is used in 21/rb (<a href="21-rb.html#SP18">&#167;18</a>).</p>
<p class="inwebparagraph"><a id="SP25_1"></a><b>&#167;25.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index the italicised text to do with the rule</span> <span class="cwebmacronumber">25.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;i&gt;%+W"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;italicised_text</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rc</span><span class="element">.scene_context</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" during "</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = </span><span class="identifier">PL::Scenes::get_name</span><span class="plain">(</span><span class="identifier">rc</span><span class="element">.scene_context</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">SW</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;/i&gt;&amp;nbsp;&amp;nbsp;"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_2"></a><b>&#167;25.2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_PASTEABLE_RULE_NAME_LENGTH</span><span class="plain"> 500</span>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Index the rule name along with Javascript buttons</span> <span class="cwebmacronumber">25.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"800000"</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">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;"</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="identifier">HTML::Javascript::paste_stream</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&lt;i&gt;name&lt;/i&gt; "</span><span class="plain">);</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="string">"The %W is not listed in the %W rulebook.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">, </span><span class="identifier">owner</span><span class="plain">-</span><span class="element">&gt;primary_name</span><span class="plain">);</span>
<span class="identifier">HTML::Javascript::paste_stream</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&lt;i&gt;unlist&lt;/i&gt;"</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain">=0, </span><span class="identifier">c</span><span class="plain">=0; </span><span class="identifier">l</span><span class="plain">&lt;26; </span><span class="identifier">l</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">]) {</span>
<span class="identifier">c</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;"</span><span class="plain">);</span>
<span class="identifier">Index::extra_link_with</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 1000000+</span><span class="identifier">R</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="string">"responses"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d"</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_3"></a><b>&#167;25.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index any response texts in the rule</span> <span class="cwebmacronumber">25.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain">=0, </span><span class="identifier">c</span><span class="plain">=0; </span><span class="identifier">l</span><span class="plain">&lt;26; </span><span class="identifier">l</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">]) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == 0) </span><span class="identifier">Index::extra_div_open_nested</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 1000000+</span><span class="identifier">R</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, 2);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="functiontext">Strings::index_response</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">]);</span>
<span class="identifier">c</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> &gt; 0) </span><span class="identifier">Index::extra_div_close_nested</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">no_responses_indexed</span><span class="plain"> = </span><span class="identifier">c</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_4"></a><b>&#167;25.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index some text extracted from the first line of the otherwise anonymous rule</span> <span class="cwebmacronumber">25.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pn</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">)))) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(%+W"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"; ..."</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">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_5"></a><b>&#167;25.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index a link to the first line of the rule's definition</span> <span class="cwebmacronumber">25.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pn</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">))))</span>
<span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">)));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_6"></a><b>&#167;25.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index the small type rule numbering</span> <span class="cwebmacronumber">25.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">smaller\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d"</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</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">"primitive"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_7"></a><b>&#167;25.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index any applicability conditions</span> <span class="cwebmacronumber">25.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">acl</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">acl</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain">; </span><span class="identifier">acl</span><span class="plain">; </span><span class="identifier">acl</span><span class="plain"> = </span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;next_applicability_condition</span><span class="plain">) {</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;where_imposed</span><span class="plain">)));</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;%+W"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">acl</span><span class="plain">-</span><span class="element">&gt;where_imposed</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. Actor testing. </b>With some rules (those which have I7 definitions and which are action based),
it's possible to change the way that applicability testing is done. Since this
can only affect rules we compile ourselves, we ignore all of these calls for
rules with I6 definitions, i.e., where <code class="display"><span class="extract">defn_as_phrase</span></code> is <code class="display"><span class="extract">NULL</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::set_always_test_actor</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) {</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd</span><span class="plain"> = &amp;(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="functiontext">Phrases::Context::set_always_test_actor</span><span class="plain">(</span><span class="identifier">phrcd</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">Rules::set_never_test_actor</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) {</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd</span><span class="plain"> = &amp;(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="functiontext">Phrases::Context::set_never_test_actor</span><span class="plain">(</span><span class="identifier">phrcd</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">Rules::set_marked_for_anyone</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) {</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd</span><span class="plain"> = &amp;(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="functiontext">Phrases::Context::set_marked_for_anyone</span><span class="plain">(</span><span class="identifier">phrcd</span><span class="plain">, </span><span class="identifier">to</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">Rules::suppress_action_testing</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) {</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd</span><span class="plain"> = &amp;(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="functiontext">Phrases::Context::suppress_action_testing</span><span class="plain">(</span><span class="identifier">phrcd</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">Rules::copy_actor_test_flags</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R_to</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R_from</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">R_from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">R_to</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">"improper catf"</span><span class="plain">);</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd_from</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">R_from</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) </span><span class="identifier">phrcd_from</span><span class="plain"> = &amp;(</span><span class="identifier">R_from</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> *</span><span class="identifier">phrcd_to</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">R_to</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">) </span><span class="identifier">phrcd_to</span><span class="plain"> = &amp;(</span><span class="identifier">R_to</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phrcd_to</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">phrcd_from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">((</span><span class="functiontext">Phrases::Context::get_marked_for_anyone</span><span class="plain">(</span><span class="identifier">phrcd_from</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Phrases::Context::get_marked_for_anyone</span><span class="plain">(</span><span class="identifier">phrcd_to</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))) {</span>
<span class="functiontext">Phrases::Context::clear_always_test_actor</span><span class="plain">(</span><span class="identifier">phrcd_to</span><span class="plain">);</span>
<span class="functiontext">Phrases::Context::set_never_test_actor</span><span class="plain">(</span><span class="identifier">phrcd_to</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::rule_is_named</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;explicitly_named</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">response_message</span><span class="plain"> *</span><span class="functiontext">Rules::rule_defines_response</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">code</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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">code</span><span class="plain"> &lt; 0) </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">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">code</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::check_response_usages</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">=0; </span><span class="identifier">l</span><span class="plain">&lt;26; </span><span class="identifier">l</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_used</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">]) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">] == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">offers</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">=0; </span><span class="identifier">l</span><span class="plain">&lt;26; </span><span class="identifier">l</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">]) {</span>
<span class="identifier">c</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> &gt; 1) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">offers</span><span class="plain">, </span><span class="string">", "</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">offers</span><span class="plain">, </span><span class="string">"%c"</span><span class="plain">, </span><span class="character">'A'</span><span class="plain">+</span><span class="identifier">l</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">letter</span><span class="plain">);</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">letter</span><span class="plain">, </span><span class="character">'A'</span><span class="plain">+</span><span class="identifier">l</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_used</span><span class="plain">[</span><span class="identifier">l</span><span class="plain">]);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(3, </span><span class="identifier">letter</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == 0) </span><span class="identifier">Problems::quote_text</span><span class="plain">(4, </span><span class="string">"no lettered responses at all"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">offers</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NoSuchResponse</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but the '%2' doesn't have a response "</span>
<span class="string">"lettered '%3'. (It has %4.)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">letter</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">offers</span><span class="plain">);</span>
<span class="plain">}</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">Rules::now_rule_defines_response</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">code</span><span class="plain">, </span><span class="reserved">response_message</span><span class="plain"> *</span><span class="identifier">resp</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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 rule defines response"</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses</span><span class="plain">[</span><span class="identifier">code</span><span class="plain">] = </span><span class="identifier">resp</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::now_rule_needs_response</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">code</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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 rule uses response"</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_used</span><span class="plain">[</span><span class="identifier">code</span><span class="plain">] = </span><span class="identifier">current_sentence</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">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_value</span><span class="plain">[</span><span class="identifier">code</span><span class="plain">] = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="functiontext">Rules::unimport</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Rules::get_response_value</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">code</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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 rule uses response"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_value</span><span class="plain">[</span><span class="identifier">code</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rules::get_response_sentence</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">code</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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 rule uses response"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;lettered_responses_used</span><span class="plain">[</span><span class="identifier">code</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="functiontext">Rules::stack_frame</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">R</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</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"> &amp;(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;stack_frame</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::portable</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">R</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;first_applicability_condition</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_extern_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Modules::find</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;defn_as_phrase</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">) == </span><span class="functiontext">Modules::SR</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>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="functiontext">Rules::package</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;rule_package</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::set_always_test_actor is used in 21/fao (<a href="21-fao.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Rules::set_never_test_actor is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>), 21/fao (<a href="21-fao.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Rules::set_marked_for_anyone is used in 21/rb (<a href="21-rb.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function Rules::suppress_action_testing is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="endnote">The function Rules::copy_actor_test_flags is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="endnote">The function Rules::rule_is_named is used in 17/rs (<a href="17-rs.html#SP12_1_1">&#167;12.1.1</a>).</p>
<p class="endnote">The function Rules::rule_defines_response is used in 17/ts (<a href="17-ts.html#SP11">&#167;11</a>), 17/rs (<a href="17-rs.html#SP4">&#167;4</a>, <a href="17-rs.html#SP7_1">&#167;7.1</a>, <a href="17-rs.html#SP7_3_1">&#167;7.3.1</a>, <a href="17-rs.html#SP12_1_1">&#167;12.1.1</a>).</p>
<p class="endnote">The function Rules::check_response_usages is used in 1/mr (<a href="1-mr.html#SP4_14">&#167;4.14</a>).</p>
<p class="endnote">The function Rules::now_rule_defines_response is used in 17/rs (<a href="17-rs.html#SP12_1_1">&#167;12.1.1</a>), 26/tti (<a href="26-tti.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Rules::now_rule_needs_response is used in 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>), 17/rs (<a href="17-rs.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function Rules::get_response_value is used in 17/rs (<a href="17-rs.html#SP7_1">&#167;7.1</a>).</p>
<p class="endnote">The function Rules::get_response_sentence is used in 17/rs (<a href="17-rs.html#SP7_1">&#167;7.1</a>).</p>
<p class="endnote">The function Rules::stack_frame appears nowhere else.</p>
<p class="endnote">The function Rules::portable appears nowhere else.</p>
<p class="endnote">The function Rules::package is used in 17/rs (<a href="17-rs.html#SP5">&#167;5</a>, <a href="17-rs.html#SP7_1">&#167;7.1</a>), 22/pu (<a href="22-pu.html#SP6">&#167;6</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 21: Rules and Rulebooks.)</i></li><li><a href="21-rb.html">Continue with 'Rule Bookings'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>