1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 00:24:22 +03:00
inform7/docs/assertions-module/6-rls.html

714 lines
134 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Rules</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Rules' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#6">Chapter 6: Rules, Rulebooks and Activities</a></li><li><b>Rules</b></li></ul></div>
<p class="purpose">Rules contain imperative code which is executed when certain actions, activities or other processes are being followed.</p>
<ul class="toc"><li><a href="6-rls.html#SP1">&#167;1. Introduction</a></li><li><a href="6-rls.html#SP3">&#167;3. Names of rules</a></li><li><a href="6-rls.html#SP7">&#167;7. The kind of a rule</a></li><li><a href="6-rls.html#SP9">&#167;9. Defining rules with imperative I7 code</a></li><li><a href="6-rls.html#SP11">&#167;11. Defining rules with Inter functions</a></li><li><a href="6-rls.html#SP12">&#167;12. Logging</a></li><li><a href="6-rls.html#SP13">&#167;13. Equality and priority</a></li><li><a href="6-rls.html#SP15">&#167;15. Applicability constraints</a></li><li><a href="6-rls.html#SP17">&#167;17. Automatic placement into rulebooks</a></li><li><a href="6-rls.html#SP18">&#167;18. Actor testing</a></li><li><a href="6-rls.html#SP19">&#167;19. Responses</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction. </b>Rule and phrase definitions have a similar syntax, in some ways &mdash; they open
with a declaration, there's a colon, and then we (often) have a block of
imperative code to show what they do:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">RULE</span><span class="plain-syntax"> </span><span class="identifier-syntax">PHRASE</span>
<span class="identifier-syntax">Before</span><span class="plain-syntax"> </span><span class="identifier-syntax">eating</span><span class="plain-syntax">: </span><span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">extinguish</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">candle</span><span class="plain-syntax">):</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"The candle flickers ominously."</span><span class="plain-syntax"> </span><span class="identifier-syntax">now</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">unlit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"Suddenly [the C] blows out."</span>
</pre>
<p class="commentary">Despite the similarities, rules are not the same thing as phrases. Some rules,
such as the one in this example, give a definition which looks like the body
of a phrase, and indeed inside the compiler it is stored as such, in the
<span class="extract"><span class="extract-syntax">defn_as_I7_source</span></span> field of a <a href="6-rls.html#SP1" class="internal">rule</a>. But other rules are written quite
differently:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">can</span><span class="plain-syntax">'</span><span class="identifier-syntax">t</span><span class="plain-syntax"> </span><span class="identifier-syntax">reach</span><span class="plain-syntax"> </span><span class="identifier-syntax">inside</span><span class="plain-syntax"> </span><span class="identifier-syntax">rooms</span><span class="plain-syntax"> </span><span class="identifier-syntax">rule</span><span class="plain-syntax"> </span><span class="identifier-syntax">translates</span><span class="plain-syntax"> </span><span class="identifier-syntax">into</span><span class="plain-syntax"> </span><span class="identifier-syntax">Inter</span><span class="plain-syntax"> </span><span class="identifier-syntax">as</span><span class="plain-syntax"> </span><span class="string-syntax">"CANT_REACH_INSIDE_ROOMS_R"</span><span class="plain-syntax">.</span>
</pre>
<p class="commentary">and this one is defined by a low-level Inter function, and not a phrase at all.
In any case, rules and phrases have quite different header syntax, and have
different dynamics altogether. In short, then: rules are not phrases.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax">; </span><span class="comment-syntax"> name of the rule being booked</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_of_rule</span><span class="plain-syntax">; </span><span class="comment-syntax"> determined from its rulebook(s)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">rulebook</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_of_rule_set_from</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">imperative_defn</span><span class="plain-syntax"> *</span><span class="identifier-syntax">defn_as_I7_source</span><span class="plain-syntax">; </span><span class="comment-syntax"> if defined by an I7 id_body</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">shared_variable_access_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variables_visible_in_definition</span><span class="plain-syntax">; </span><span class="comment-syntax"> if so</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">defn_as_Inter_function</span><span class="plain-syntax">; </span><span class="comment-syntax"> if not</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">automatic_booking</span><span class="plain-syntax">; </span><span class="comment-syntax"> how this is placed in rulebooks</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">applicability_constraints</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><a href="6-rls.html#SP15" class="internal">applicability_constraint</a>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">allows_responses</span><span class="plain-syntax">; </span><span class="comment-syntax"> was this rule explicitly named when created?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">rule_response</span><span class="plain-syntax"> </span><span class="identifier-syntax">responses</span><span class="plain-syntax">[26]; </span><span class="comment-syntax"> responses (A), (B), ...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">rule_compilation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">rule</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure rule is accessed in 3/nuor, 3/dbtr, 3/rpr, 4/ass, 5/id, 5/idf, 5/adf, 5/tpf, 5/po, 5/rf, 5/rcd, 6/rlb, 6/fao, 6/act, 6/sv, 7/tc, 7/tbl, 7/eqt and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Rules are created before their definitions can be parsed or compiled. A
typical rule like so:
</p>
<blockquote>
<p>Before eating (this is the must say grace rule): ...</p>
</blockquote>
<p class="commentary">causes "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 it would have
been if the "(this is... )" part had been omitted.
</p>
<p class="commentary">Some rules are nameless, and there can be any number of those. But if a rule
does have a name, then that name must be unique. The following fetches the
rule called <span class="extract"><span class="extract-syntax">W</span></span>, creating it if necessary.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::obtain</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Rules::obtain</span></span>:<br/><a href="6-rls.html#SP11">&#167;11</a><br/>Rule Family - <a href="5-rf.html#SP5">&#167;5</a>, <a href="5-rf.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">allow_responses</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Articles::remove_the</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="6-rls.html#SP5" class="function-link"><span class="function-syntax">Rules::by_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule_set_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variables_visible_in_definition</span><span class="plain-syntax"> = </span><a href="6-sv.html#SP8" class="function-link"><span class="function-syntax">SharedVariables::new_access_list</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">automatic_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">applicability_constraints</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allows_responses</span><span class="plain-syntax"> = </span><span class="identifier-syntax">allow_responses</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">l</span><span class="plain-syntax">&lt;26; </span><span class="identifier-syntax">l</span><span class="plain-syntax">++) </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">] = </span><a href="6-rls.html#SP20" class="function-link"><span class="function-syntax">Rules::new_rule_response</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RTRules::new_compilation_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="6-rls.html#SP3" class="function-link"><span class="function-syntax">Rules::vet_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="6-rls.html#SP5" class="function-link"><span class="function-syntax">Rules::register_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Names of rules. </b>Rule names must pass the following sanity check:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">PM_RuleWithComma_issued_at</span><span class="plain-syntax"> = -1;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::vet_name</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Rules::vet_name</span></span>:<br/><a href="6-rls.html#SP2">&#167;2</a><br/>Rule Family - <a href="5-rf.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;unsuitable-name&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PM_RuleWithComma_issued_at</span><span class="plain-syntax"> != </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PM_RuleWithComma_issued_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RuleWithComma</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a rule name is not allowed to contain punctuation, or to consist only "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of an article like 'a' or 'an', or to contain double-quoted text"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"because this leads to too much ambiguity later on."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The names of rules become proper nouns in the lexicon. There are typically some
hundreds of these and 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>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;rule-name-formal&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">rule</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::register_name</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Rules::register_name</span></span>:<br/><a href="6-rls.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RULE_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;rule-name-formal&gt;(R-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">)) </span><span class="identifier-syntax">mc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MISCELLANEOUS_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Nouns::new_proper_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">NEUTER_GENDER</span><span class="plain-syntax">, </span><span class="identifier-syntax">ADD_TO_LEXICON_NTOPT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mc</span><span class="plain-syntax">, </span><span class="identifier-syntax">Rvalues::from_rule</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">Task::language_of_syntax</span><span class="plain-syntax">());</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::by_name</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Rules::by_name</span></span>:<br/><a href="6-rls.html#SP2">&#167;2</a>, <a href="6-rls.html#SP6">&#167;6</a><br/>Rule Family - <a href="5-rf.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Articles::remove_the</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RULE_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;rule-name-formal&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">mc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MISCELLANEOUS_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexicon::retrieve</span><span class="plain-syntax">(</span><span class="identifier-syntax">mc</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_CONSTANT_construction</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_rule</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::to_rule</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Which we wrap in a Preform nonterminal thus:
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;rule-name&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">Articles::remove_the</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">rule</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">R</span><span class="Preform-plain-syntax"> = </span><a href="6-rls.html#SP5" class="function-link"><span class="Preform-function-syntax">Rules::by_name</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">R</span><span class="Preform-plain-syntax">) {</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">R</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. The kind of a rule. </b>Given that Inform authors can refer to (named) rules as constant values, they
need to have kinds, and it is not obvious what those should be. Clearly
some form of "K-based rule producing L" would be reasonable, but leaving K
and L just to be "value" &mdash; as the earliest versions of Inform 7 did, in the
mid-2000s &mdash; would be indefinite. Constants should always have definite kinds,
because otherwise kind inference will fail on phrases like:
</p>
<blockquote>
<p>let R be the foo rule;</p>
</blockquote>
<p class="commentary">So we have to give each rule a definite kind. Unfortunately for us, there is
no indication of that kind in its declaration, as such: we must infer the
kind from how the rule is used, that is, from the rulebook it is put into.
And since a rule can be in multiple rulebooks, we have to check that this
does not lead to an inconsistency.
</p>
<p class="commentary">The following function is called when a rule is added to a rulebook:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::set_kind_from</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Rules::set_kind_from</span></span>:<br/>Rule Placement Requests - <a href="3-rpr.html#SP15_1">&#167;15.1</a><br/>Rule Bookings - <a href="6-rb.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">rulebook</span><span class="plain-syntax"> *</span><span class="identifier-syntax">RB</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="6-rlb.html#SP2_4" class="function-link"><span class="function-syntax">Rulebooks::contains_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">RB</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">kind_of_rule</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">kind_of_rule</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">) != </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">B2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">P1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">P2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::binary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">B1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">P1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::binary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">B2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">P2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">B1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">P1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(5, </span><span class="identifier-syntax">B2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(6, </span><span class="identifier-syntax">P2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording_as_source</span><span class="plain-syntax">(7, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule_set_from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording_as_source</span><span class="plain-syntax">(8, </span><span class="identifier-syntax">RB</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RuleInIncompatibleRulebooks</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You've asked to put the rule '%2' into the rulebook %8, which is based "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"on %5 and produces %6; but it was originally written to go into a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"rulebook of a different kind, %7, which is based on %3 and produces %4. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Because those kinds are different, '%2' can't go into %8."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule_set_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RB</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>If a rule has no known kind &mdash; if it is not in a rulebook, for example &mdash;
then the following says it is an action-based rule producing nothing, unless
we are in Basic Inform only, in which case it is a nothing-based rule producing
nothing.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::to_kind</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_ACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">actions</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::binary_con</span><span class="plain-syntax">(</span><span class="identifier-syntax">CON_rule</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_action_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::binary_con</span><span class="plain-syntax">(</span><span class="identifier-syntax">CON_rule</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Defining rules with imperative I7 code. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::set_imperative_definition</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Rules::set_imperative_definition</span></span>:<br/>Rule Family - <a href="5-rf.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">imperative_defn</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax"> = </span><span class="identifier-syntax">id</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CompileImperativeDefn::set_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">body_of_defn</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTRules::iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">imperative_defn</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::get_imperative_definition</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Rules::get_imperative_definition</span></span>:<br/>Rule Family - <a href="5-rf.html#SP8_1_1">&#167;8.1.1</a><br/>Runtime Context Data - <a href="5-rcd.html#SP6">&#167;6</a><br/>Rule Bookings - <a href="6-rb.html#SP6">&#167;6</a><br/>Booking Lists - <a href="6-bl.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Inside such a definition, certain shared variables may be in scope. For
example, if a rule is in an activity rulebook, then it will be able to see
the variables belonging to that activity.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::put_variables_in_scope</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Rules::put_variables_in_scope</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">shared_variable_access_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">access</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="6-sv.html#SP10" class="function-link"><span class="function-syntax">SharedVariables::append_access_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variables_visible_in_definition</span><span class="plain-syntax">, </span><span class="identifier-syntax">access</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::put_action_variables_in_scope</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IF_MODULE</span>
<span class="plain-syntax"> </span><a href="6-rls.html#SP10" class="function-link"><span class="function-syntax">Rules::put_variables_in_scope</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">all_nonempty_stacked_action_vars</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP10" class="function-link"><span class="function-syntax">Rules::all_action_processing_variables</span></a><span class="plain-syntax">())</span>
<span class="plain-syntax"> </span><a href="6-rls.html#SP10" class="function-link"><span class="function-syntax">Rules::put_variables_in_scope</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="6-rls.html#SP10" class="function-link"><span class="function-syntax">Rules::all_action_processing_variables</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">shared_variable_access_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">all_action_processing_vars</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">shared_variable_access_list</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::all_action_processing_variables</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">all_action_processing_vars</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">all_action_processing_vars</span><span class="plain-syntax"> = </span><a href="6-sv.html#SP8" class="function-link"><span class="function-syntax">SharedVariables::new_access_list</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rulebook</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RB_action_processing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax">) </span><a href="6-sv.html#SP9" class="function-link"><span class="function-syntax">SharedVariables::add_set_to_access_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">all_action_processing_vars</span><span class="plain-syntax">, </span><a href="6-rlb.html#SP11" class="function-link"><span class="function-syntax">Rulebooks::variables</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">B</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">all_action_processing_vars</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Defining rules with Inter functions. </b>When a rule is really just a wrapper for an Inter-level function, as here:
</p>
<blockquote>
<p>The can't reach inside rooms rule translates into Inter as |"CANT_REACH_INSIDE_ROOMS_R"|.</p>
</blockquote>
<p class="commentary">...it has no <span class="extract"><span class="extract-syntax">defn_as_I7_source</span></span> and instead has the name of the Inter function
stored in <span class="extract"><span class="extract-syntax">defn_as_Inter_function</span></span>.
</p>
<p class="commentary">Here <span class="extract"><span class="extract-syntax">W</span></span> is the rule's name, say "can't reach inside rooms rule", and <span class="extract"><span class="extract-syntax">FW</span></span>
is wording which should contain just the double-quoted function name.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::declare_Inter_rule</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Rules::declare_Inter_rule</span></span>:<br/>Translation Requests - <a href="3-tr.html#SP8_2_2">&#167;8.2.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">FW</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="6-rls.html#SP2" class="function-link"><span class="function-syntax">Rules::obtain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax">, </span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Logging. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::log</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Rules::log</span></span>:<br/>Rule Bookings - <a href="6-rb.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;null-rule&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"['%W':"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"["</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">defn_as_I7_source</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$R]"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">body_of_defn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%S]"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d]"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Equality and priority. </b>Two different <a href="6-rls.html#SP1" class="internal">rule</a> pointers can in fact refer to what will be the same rule
at run-time if this should happen:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">alpha</span><span class="plain-syntax"> </span><span class="identifier-syntax">rule</span><span class="plain-syntax"> </span><span class="identifier-syntax">translates</span><span class="plain-syntax"> </span><span class="identifier-syntax">into</span><span class="plain-syntax"> </span><span class="identifier-syntax">Inter</span><span class="plain-syntax"> </span><span class="identifier-syntax">as</span><span class="plain-syntax"> |</span><span class="string-syntax">"SAME_R"</span><span class="plain-syntax">|.</span>
<span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">beta</span><span class="plain-syntax"> </span><span class="identifier-syntax">rule</span><span class="plain-syntax"> </span><span class="identifier-syntax">translates</span><span class="plain-syntax"> </span><span class="identifier-syntax">into</span><span class="plain-syntax"> </span><span class="identifier-syntax">Inter</span><span class="plain-syntax"> </span><span class="identifier-syntax">as</span><span class="plain-syntax"> |</span><span class="string-syntax">"SAME_R"</span><span class="plain-syntax">|.</span>
</pre>
<p class="commentary">And so we have the following:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::eq</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Rules::eq</span></span>:<br/>Booking Lists - <a href="6-bl.html#SP5_2">&#167;5.2</a>, <a href="6-bl.html#SP5_3">&#167;5.3</a>, <a href="6-bl.html#SP5_6_1">&#167;5.6.1</a>, <a href="6-bl.html#SP6">&#167;6</a>, <a href="6-bl.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R1</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::defined</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R1</span><span class="plain-syntax">)) || (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::defined</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R2</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax"> != </span><span class="identifier-syntax">R1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::ne</span><span class="plain-syntax">(</span><span class="identifier-syntax">R1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax">, </span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R1</span><span class="plain-syntax"> != </span><span class="identifier-syntax">R2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::defined</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_Inter_function</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>This <span class="extract"><span class="extract-syntax">strcmp</span></span>-like function is intended to be used in sorting algorithms,
and returns 1 if <span class="extract"><span class="extract-syntax">R1</span></span> is more specific than <span class="extract"><span class="extract-syntax">R2</span></span>, -1 if <span class="extract"><span class="extract-syntax">R2</span></span> is more specific
than <span class="extract"><span class="extract-syntax">R1</span></span>, or 0 if they are equally good.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::cmp</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Rules::cmp</span></span>:<br/>Rule Bookings - <a href="6-rb.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R1</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">log_this</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">imperative_defn</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">, *</span><span class="identifier-syntax">id2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">phrcd1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">phrcd2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">id1</span><span class="plain-syntax">) </span><span class="identifier-syntax">phrcd1</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">id1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">body_of_defn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">runtime_context_data</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">id2</span><span class="plain-syntax">) </span><span class="identifier-syntax">phrcd2</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">id2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">body_of_defn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">runtime_context_data</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP3" class="function-link"><span class="function-syntax">RuntimeContextData::compare_specificity</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">phrcd1</span><span class="plain-syntax">, </span><span class="identifier-syntax">phrcd2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">log_this</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Decided by Law %S that "</span><span class="plain-syntax">, </span><span class="identifier-syntax">Specifications::law_applied</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Decided that "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> -1: </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(2) is more specific than (1)\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"they are equally specific\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(1) is more specific than (2)\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Applicability constraints. </b>Applicability constraints 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="commentary">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 constraints attached to a given rule, so these are stored in a list.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_of_condition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sense_of_applicability</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">TRUE</span></span><span class="comment-syntax"> if condition must hold for rule to have effect</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">substituted_rule</span><span class="plain-syntax">; </span><span class="comment-syntax"> rule to use instead if not, or </span><span class="extract"><span class="extract-syntax">NULL</span></span><span class="comment-syntax"> to do nothing</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">where_imposed</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::impose_constraint</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Rules::impose_constraint</span></span>:<br/>Rule Placement Requests - <a href="3-rpr.html#SP7">&#167;7</a>, <a href="3-rpr.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sense</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ac</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">text_of_condition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sense_of_applicability</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sense</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_imposed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substituted_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">ac</span><span class="plain-syntax">, </span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">applicability_constraints</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure applicability_constraint is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>If under some circumstances one rule is substituted for another, there's
the potential for something type-unsafe to happen, and the following checks
that it doesn't.
</p>
<p class="commentary">Note that we allow a rule based on nothing to substitute for a rule based on
some value (or on an action) because of course it's perfectly typesafe to ignore
the basis value entirely.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::check_constraints_are_typesafe</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Rules::check_constraints_are_typesafe</span></span>:<br/>Rule Family - <a href="5-rf.html#SP16">&#167;16</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">KR</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ac</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">ac</span><span class="plain-syntax">, </span><span class="reserved-syntax">applicability_constraint</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">applicability_constraints</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substituted_rule</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">KS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substituted_rule</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_of_rule</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">B2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">P1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">P2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::binary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">KR</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">B1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">P1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::binary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">KS</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">B2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">P2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">B1</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">B1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">B2</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">B2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">P1</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">P1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">P2</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">P2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">B2</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_void</span><span class="plain-syntax">)) </span><span class="identifier-syntax">B2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::binary_con</span><span class="plain-syntax">(</span><span class="identifier-syntax">CON_rule</span><span class="plain-syntax">, </span><span class="identifier-syntax">B1</span><span class="plain-syntax">, </span><span class="identifier-syntax">P1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::binary_con</span><span class="plain-syntax">(</span><span class="identifier-syntax">CON_rule</span><span class="plain-syntax">, </span><span class="identifier-syntax">B2</span><span class="plain-syntax">, </span><span class="identifier-syntax">P2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">, </span><span class="identifier-syntax">K1</span><span class="plain-syntax">) != </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_imposed</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_imposed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">ac</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substituted_rule</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">KR</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(5, </span><span class="identifier-syntax">KS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RulesCantInterchange</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1 you've asked to use the rule '%2' in place of '%3', "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but one is based on %4 whereas the other is %5, and those aren't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"interchangeable."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Automatic placement into rulebooks. </b>Some rules 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="commentary">But others have their placements made implicitly in their definitions:
</p>
<blockquote>
<p>Before eating something: ...</p>
</blockquote>
<p class="commentary">(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="commentary">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="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::request_automatic_placement</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Rules::request_automatic_placement</span></span>:<br/>Rule Family - <a href="5-rf.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">automatic_booking</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">automatic_booking</span><span class="plain-syntax"> = </span><a href="6-rb.html#SP3" class="function-link"><span class="function-syntax">RuleBookings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="6-rb.html#SP5" class="function-link"><span class="function-syntax">RuleBookings::request_automatic_placement</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">automatic_booking</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. 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.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::set_always_test_actor</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Rules::set_always_test_actor</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">defn_as_I7_source</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcd</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP1" class="function-link"><span class="function-syntax">RuntimeContextData::of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ActionRules::set_always_test_actor</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::set_never_test_actor</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Rules::set_never_test_actor</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">defn_as_I7_source</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcd</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP1" class="function-link"><span class="function-syntax">RuntimeContextData::of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ActionRules::set_never_test_actor</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::set_marked_for_anyone</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">defn_as_I7_source</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcd</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP1" class="function-link"><span class="function-syntax">RuntimeContextData::of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ActionRules::set_marked_for_anyone</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::suppress_action_testing</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">defn_as_I7_source</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcd</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP1" class="function-link"><span class="function-syntax">RuntimeContextData::of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ActionRules::suppress_action_testing</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::copy_actor_test_flags</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R_to</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R_from</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R_from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"improper catf"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcd_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">) </span><span class="identifier-syntax">rcd_from</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP1" class="function-link"><span class="function-syntax">RuntimeContextData::of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R_from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">id_runtime_context_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcd_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_to</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">) </span><span class="identifier-syntax">rcd_to</span><span class="plain-syntax"> = </span><a href="5-rcd.html#SP1" class="function-link"><span class="function-syntax">RuntimeContextData::of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R_to</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defn_as_I7_source</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rcd_to</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">rcd_from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">ActionRules::get_marked_for_anyone</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd_from</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ActionRules::get_marked_for_anyone</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd_to</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ActionRules::clear_always_test_actor</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd_to</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ActionRules::set_never_test_actor</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcd_to</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Responses. </b>Not all rules can have responses: for example, timed event rules cannot.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::rule_allows_responses</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allows_responses</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>In Inform source text, the different response texts for a rule are lettered
'A' to at most 'Z': inside the compiler, they are numbered 0 to 25. For each
possibility we store one of these:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">rule_response</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">response_message</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">used</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">content</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">rule_response</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">rule_response</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::new_rule_response</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Rules::new_rule_response</span></span>:<br/><a href="6-rls.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rule_response</span><span class="plain-syntax"> </span><span class="identifier-syntax">rr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rr</span><span class="plain-syntax">.</span><span class="element-syntax">message</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rr</span><span class="plain-syntax">.</span><span class="element-syntax">used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rr</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rr</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::get_response_replacement_wording</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">26</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">].</span><span class="element-syntax">content</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::get_response_sentence</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">26</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">].</span><span class="element-syntax">used</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure rule_response is accessed in 3/nuor and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b>When a response is defined in the body of a rule, the <span class="extract"><span class="extract-syntax">message</span></span> is
created with <a href="6-rls.html#SP21" class="internal">Rules::set_response</a>:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::set_response</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code</span><span class="plain-syntax">, </span><span class="identifier-syntax">response_message</span><span class="plain-syntax"> *</span><span class="identifier-syntax">resp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null rule defines response"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">26</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"response out of range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">].</span><span class="element-syntax">message</span><span class="plain-syntax"> = </span><span class="identifier-syntax">resp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">response_message</span><span class="plain-syntax"> *</span><span class="function-syntax">Rules::get_response</span><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">26</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">].</span><span class="element-syntax">message</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>When a response is referred to elsewhere, for example in source text which
tries to change its wording to the new text <span class="extract"><span class="extract-syntax">W</span></span>, the following is called:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::now_rule_needs_response</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Rules::now_rule_needs_response</span></span>:<br/>Assertions - <a href="4-ass.html#SP6_3_41_6">&#167;6.3.41.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null rule uses response"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">code</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">26</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"response out of range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">].</span><span class="element-syntax">used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">].</span><span class="element-syntax">content</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>That function did not check that the rule actually had the response it
was trying to change &mdash; it didn't check this because, for timing reasons, it
couldn't yet do so. Instead, we check retrospectively, at a time when all
response messages have been discovered:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Rules::check_response_usages</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">l</span><span class="plain-syntax">&lt;26; </span><span class="identifier-syntax">l</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">].</span><span class="identifier-syntax">used</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">].</span><span class="element-syntax">message</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-rls.html#SP23_1" class="named-paragraph-link"><span class="named-paragraph">Throw a used but never defined problem</span><span class="named-paragraph-number">23.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23_1" class="paragraph-anchor"></a><b>&#167;23.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Throw a used but never defined problem</span><span class="named-paragraph-number">23.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">offers</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">l</span><span class="plain-syntax">&lt;26; </span><span class="identifier-syntax">l</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">].</span><span class="element-syntax">message</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">offers</span><span class="plain-syntax">, </span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">offers</span><span class="plain-syntax">, </span><span class="string-syntax">"%c"</span><span class="plain-syntax">, </span><span class="character-syntax">'A'</span><span class="plain-syntax">+</span><span class="identifier-syntax">l</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">offers</span><span class="plain-syntax">, </span><span class="string-syntax">"no lettered responses at all"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter</span><span class="plain-syntax">, </span><span class="character-syntax">'A'</span><span class="plain-syntax">+</span><span class="identifier-syntax">l</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">].</span><span class="element-syntax">used</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">responses</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">].</span><span class="element-syntax">used</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_stream</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">letter</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_stream</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">offers</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NoSuchResponse</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but the '%2' doesn't have a response lettered '%3'. (It has %4.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">letter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">offers</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-rls.html#SP23">&#167;23</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="5-rcd.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-bv.html">2</a></li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresschapter"><a href="4-nr.html">4</a></li><li class="progresschapter"><a href="5-id.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresscurrent">rls</li><li class="progresssection"><a href="6-rb.html">rb</a></li><li class="progresssection"><a href="6-bl.html">bl</a></li><li class="progresssection"><a href="6-rlb.html">rlb</a></li><li class="progresssection"><a href="6-fao.html">fao</a></li><li class="progresssection"><a href="6-act.html">act</a></li><li class="progresssection"><a href="6-sv.html">sv</a></li><li class="progresschapter"><a href="7-tc.html">7</a></li><li class="progresschapter"><a href="8-kpr.html">8</a></li><li class="progressnext"><a href="6-rb.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>