<pclass="purpose">To work out bitmaps of nonterminal incidences in grammar.</p>
<ulclass="toc"><li><ahref="4-ni.html#SP1">§1. Introduction</a></li><li><ahref="4-ni.html#SP2">§2. Incidence bits</a></li><li><ahref="4-ni.html#SP3">§3. The NTI of a word</a></li><li><ahref="4-ni.html#SP6">§6. Range requirements</a></li><li><ahref="4-ni.html#SP9">§9. Basic range requirements</a></li><li><ahref="4-ni.html#SP11">§11. Concatenation of range requirements</a></li><li><ahref="4-ni.html#SP17">§17. Disjunction of range requirements</a></li><li><ahref="4-ni.html#SP22">§22. Range requirement simplification</a></li><li><ahref="4-ni.html#SP25">§25. Calculations</a></li><li><ahref="4-ni.html#SP26">§26. Customisation</a></li></ul><hrclass="tocbar">
<pclass="commentary firstcommentary"><aid="SP1"></a><b>§1. Introduction. </b>The "nonterminal incidences" system provides one of two optimisations enabling
the Preform parser quickly to reject non-matches, the other being
<ahref="4-le.html"class="internal">Length Extremes</a>, which is easier to understand.
</p>
<pclass="commentary">It may elucidate both to see the actual optimisation data for nonterminals
as used in a typical run of Inform 7 — see <ahref="../inform7/M-pm.html"class="internal">Performance Metrics (in inform7)</a>.
</p>
<pclass="commentary firstcommentary"><aid="SP2"></a><b>§2. Incidence bits. </b>Each NT is assigned an "incidence bit", but this is generated on demand;
<spanclass="extract"><spanclass="extract-syntax">nt_incidence_bit</span></span> is -1 until it is allocated, and is otherwise an integer in
which only one bit is set, and always in the lowest 32 bits (since we won't
assume integers are any larger than that).
</p>
<pclass="commentary">The lowest 6 bits are reserved — see <ahref="4-ni.html#SP27"class="internal">NTI::give_nt_reserved_incidence_bit</a>
below — but bits 7 to 32 are free, and the following function cycles through
those 26 possibilities. Those 26 don't have any semantic significance; they
simply divide up the nonterminals into 26 different bins of roughly equal
sizes, in the same sort of way that keys are divided up in hash tables.
<pclass="commentary firstcommentary"><aid="SP3"></a><b>§3. The NTI of a word. </b>The vocabulary system provides an integer called the "nonterminal incidence",
or NTI, attached to each different word in our vocabulary. We can read this
with <ahref="2-vcb.html#SP12"class="internal">Vocabulary::get_nti</a> and write it with <ahref="2-vcb.html#SP12"class="internal">Vocabulary::set_nti</a>; if
we don't, it remains 0.
</p>
<pclass="commentary">The NTI for a word will be a bitmap of the incidence bits for each NT whose
grammar includes that word.
</p>
<pclass="commentary">So, for example, if the word "plus" appears in the grammar defining
<edwardian-trousers> and <arithmetic-operation>, but no others, then
its NTI would be the incidence bit for <edwardian-trousers> together
with that for <arithmetic-operation>.
</p>
<pclass="commentary">To build that, we'll use the following:
<pclass="commentary firstcommentary"><aid="SP6"></a><b>§6. Range requirements. </b>The NTI bitmaps for words are not easy to put together, but provided this
can be done correctly then we can benefit from systematic criteria to reject
doomed matches quickly when parsing. For example, suppose we have grammar:
<pclass="commentary">and we are trying to match the text "galvanised zinc". The Optimiser has
already determined that the word "galvanised" is not used anywhere in the
grammar for <fish>, and similarly the word "zinc" — so neither word has
the incidence bit for <fish> in its NTI. But the Optimiser can also see that
each of the three productions involves <fish> somewhere — not always in
the same position, but somewhere. It therefore knows that for a wording to
match, one of the words must have the <fish> incidence bit. And since
neither "galvanised" nor "zinc" have it, the wording "galvanised zinc"
cannot be a match.
</p>
<pclass="commentary firstcommentary"><aid="SP7"></a><b>§7. </b>That example was contrived, but when this idea is taken further in a
more systematic way it produces very large speed gains, because it allows
a few fast bitwise operations to avoid the need for slow parsing processes
to reach an inevitably doomed conclusion.
</p>
<pclass="commentary">The above idea can be applied equally well to matching text against a
nonterminal, production or ptoken, so all three have a <ahref="4-ni.html#SP7"class="internal">nti_constraint</a>
object. A NTIC encodes six rules, applying to a word range in three ways:
</p>
<ulclass="items"><li>(a) D for "disjunction", or logical or. One of the words must satisfy this.
</li><li>(b) C for "conjunction", or logical and. All of the words must satisfy this.
</li><li>(c) F for "first". The first word must satisfy this.
</li></ul>
<pclass="commentary">And a rule can apply to the NTI bits in two ways:
</p>
<ulclass="items"><li>(i) W for "weak". A word passes if it has one of these NTI bits.
</li><li>(ii) S for "strong". A word passes if it has all of these NTI bits.
</li></ul>
<pclass="commentary">That makes six combinations in all: DW, DS, CW, CS, FW, and FS.
</p>
<pclass="commentary">For example, suppose a NTIC has <spanclass="extract"><spanclass="Preform-extract-syntax">DS_req</span></span> set to <spanclass="extract"><spanclass="Preform-extract-syntax">0x280</span></span>— i.e., to a bitmap
in which bits 7 and 9 are set (counting upwards from 0). This is then saying
that a word range such as "sense and prejudice" can only be a match if one
of the three words "sense", "and" or "prejudice" has both bits 7 and 9 set.
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">there_are_no_requirements</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> if set, ignore all six bitmaps</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">DW_req</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> one of the words has one of these bits</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">DS_req</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> one of the words has all of these bits</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">CW_req</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> all of the words have one of these bits</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">CS_req</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> all of the words have all of these bits</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">FW_req</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the first word has one of these bits</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">FS_req</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the first word has all of these bits</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">ditto_flag</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> this production has the same constraint as the previous one</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><ahref="3-wrd.html#SP8"class="function-link"><spanclass="function-syntax">Wordings::length</span></a><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">W</span><spanclass="plain-syntax">) == </span><spanclass="constant-syntax">1</span><spanclass="plain-syntax">) </span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP8_1"class="named-paragraph-link"><spanclass="named-paragraph">Perform C, D and F tests on a single word</span><spanclass="named-paragraph-number">8.1</span></a></span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((</span><spanclass="identifier-syntax">C_set</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">D_set</span><spanclass="plain-syntax">)) </span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP8_2"class="named-paragraph-link"><spanclass="named-paragraph">Perform C, D and F tests</span><spanclass="named-paragraph-number">8.2</span></a></span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">else</span><spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">C_set</span><spanclass="plain-syntax">) </span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP8_3"class="named-paragraph-link"><spanclass="named-paragraph">Perform C and F tests</span><spanclass="named-paragraph-number">8.3</span></a></span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">else</span><spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">D_set</span><spanclass="plain-syntax">) </span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP8_4"class="named-paragraph-link"><spanclass="named-paragraph">Perform D and F tests</span><spanclass="named-paragraph-number">8.4</span></a></span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">else</span><spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">F_set</span><spanclass="plain-syntax">) </span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP8_5"class="named-paragraph-link"><spanclass="named-paragraph">Perform F test</span><spanclass="named-paragraph-number">8.5</span></a></span><spanclass="plain-syntax">;</span>
<pclass="commentary firstcommentary"><aid="SP8_1"></a><b>§8.1. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Perform C, D and F tests on a single word</span><spanclass="named-paragraph-number">8.1</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">CS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">CS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">CW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">CW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
</pre>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP8">§8</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP8_2"></a><b>§8.2. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Perform C, D and F tests</span><spanclass="named-paragraph-number">8.2</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"> }</span>
<spanclass="plain-syntax"> }</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">disj</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">disj</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">DW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
</pre>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP8">§8</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP8_3"></a><b>§8.3. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Perform C and F tests</span><spanclass="named-paragraph-number">8.3</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"> }</span>
<spanclass="plain-syntax"> }</span>
</pre>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP8">§8</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP8_4"></a><b>§8.4. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Perform D and F tests</span><spanclass="named-paragraph-number">8.4</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) != (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FS_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> ((((</span><spanclass="identifier-syntax">bm</span><spanclass="plain-syntax">) & (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) && (</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">FW_req</span><spanclass="plain-syntax">)) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">;</span>
</pre>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP8">§8</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP9"></a><b>§9. Basic range requirements. </b>Determining the NTIC for a given nonterminal, production or ptoken involves
some work, and we build them iteratively, starting from something simple.
<spanclass="reserved-syntax">nti_constraint</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::each_word_must_have</span><buttonclass="popup"onclick="togglePopup('usagePopup6')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup6">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::each_word_must_have</span></span>:<br/><ahref="4-ni.html#SP25_2_1_1">§25.2.1.1</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">nonterminal</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">nt</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP11"></a><b>§11. Concatenation of range requirements. </b>Suppose we are going to match some words X, then some more words Y.
The X words have to satisfy <spanclass="extract"><spanclass="extract-syntax">X_ntic</span></span> and the Y words <spanclass="extract"><spanclass="extract-syntax">Y_ntic</span></span>. The following
function alters <spanclass="extract"><spanclass="extract-syntax">X_ntic</span></span> so that it is now a requirement for "match X and
<pclass="commentary firstcommentary"><aid="SP12"></a><b>§12. </b>The strong requirements are well-defined. Suppose all of the bits of <spanclass="extract"><spanclass="extract-syntax">m1</span></span>
are found in X, and all of the bits of <spanclass="extract"><spanclass="extract-syntax">m2</span></span> are found in Y. Then clearly
all of the bits in the union of these two sets are found in XY, and that's
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::concatenate_ds</span><buttonclass="popup"onclick="togglePopup('usagePopup8')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup8">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::concatenate_ds</span></span>:<br/><ahref="4-ni.html#SP11">§11</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP13"></a><b>§13. </b>Similarly, suppose all of the bits of <spanclass="extract"><spanclass="extract-syntax">m1</span></span> are found in every word of X,
and all of those of <spanclass="extract"><spanclass="extract-syntax">m2</span></span> are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::concatenate_cs</span><buttonclass="popup"onclick="togglePopup('usagePopup9')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup9">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::concatenate_cs</span></span>:<br/><ahref="4-ni.html#SP11">§11</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP14"></a><b>§14. </b>Now suppose that at least one bit of <spanclass="extract"><spanclass="extract-syntax">m1</span></span> can be found in X, and one bit
of <spanclass="extract"><spanclass="extract-syntax">m2</span></span> can be found in Y. This gives us two pieces of information about
XY, and we can freely choose which to go for: we may as well pick <spanclass="extract"><spanclass="extract-syntax">m1</span></span> and
say that one bit of <spanclass="extract"><spanclass="extract-syntax">m1</span></span> can be found in XY. In principle we ought to choose
the rarest for best effect, but that's too much work.
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::concatenate_dw</span><buttonclass="popup"onclick="togglePopup('usagePopup10')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup10">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::concatenate_dw</span></span>:<br/><ahref="4-ni.html#SP11">§11</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the case where we have no information about X</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> and about Y</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the general case discussed above</span>
<spanclass="plain-syntax">}</span>
</pre>
<pclass="commentary firstcommentary"><aid="SP15"></a><b>§15. </b>Now suppose that each word of X matches at least one bit of <spanclass="extract"><spanclass="extract-syntax">m1</span></span>, and
similarly for Y and <spanclass="extract"><spanclass="extract-syntax">m2</span></span>. Then each word of XY matches at least one bit of
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::concatenate_cw</span><buttonclass="popup"onclick="togglePopup('usagePopup11')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup11">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::concatenate_cw</span></span>:<br/><ahref="4-ni.html#SP11">§11</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the case where we have no information about X</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> and about Y</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> | </span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the general case discussed above</span>
<spanclass="plain-syntax">}</span>
</pre>
<pclass="commentary firstcommentary"><aid="SP16"></a><b>§16. </b>The first word of XY is the first word of X, so these are much easier:
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::concatenate_fs</span><buttonclass="popup"onclick="togglePopup('usagePopup12')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup12">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::concatenate_fs</span></span>:<br/><ahref="4-ni.html#SP11">§11</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::concatenate_fw</span><buttonclass="popup"onclick="togglePopup('usagePopup13')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup13">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::concatenate_fw</span></span>:<br/><ahref="4-ni.html#SP11">§11</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP17"></a><b>§17. Disjunction of range requirements. </b>The second operation is disjunction. Again we have words X with requirement
<spanclass="extract"><spanclass="extract-syntax">X_ntic</span></span> and Y with <spanclass="extract"><spanclass="extract-syntax">Y_ntic</span></span>, but this time we want to change <spanclass="extract"><spanclass="extract-syntax">X_ntic</span></span> so that
it is the requirement for "match either X or Y", or X/Y for short.
</p>
<pclass="commentary">This amounts to a disguised form of de Morgan's laws.
<pclass="commentary firstcommentary"><aid="SP18"></a><b>§18. </b>Suppose all of the bits of <spanclass="extract"><spanclass="extract-syntax">m1</span></span> are found in X, and all of the bits of <spanclass="extract"><spanclass="extract-syntax">m2</span></span>
are found in Y. Then the best we can say is that all of the bits in the
intersection of these two sets are found in X/Y. (If they have no bits in
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::disjoin_ds</span><buttonclass="popup"onclick="togglePopup('usagePopup15')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup15">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::disjoin_ds</span></span>:<br/><ahref="4-ni.html#SP17">§17</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP19"></a><b>§19. </b>Similarly, suppose all of the bits of <spanclass="extract"><spanclass="extract-syntax">m1</span></span> are found in every word of X,
and all of those of <spanclass="extract"><spanclass="extract-syntax">m2</span></span> are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
<pclass="commentary firstcommentary"><aid="SP20"></a><b>§20. </b>Now suppose that at least one bit of <spanclass="extract"><spanclass="extract-syntax">m1</span></span> can be found in X, and one bit
of <spanclass="extract"><spanclass="extract-syntax">m2</span></span> can be found in Y. All we can say is that one of these various bits
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::disjoin_dw</span><buttonclass="popup"onclick="togglePopup('usagePopup17')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup17">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::disjoin_dw</span></span>:<br/><ahref="4-ni.html#SP17">§17</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the case where we have no information about X</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> and about Y</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> | </span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the general case discussed above</span>
<spanclass="plain-syntax">}</span>
</pre>
<pclass="commentary firstcommentary"><aid="SP21"></a><b>§21. </b>And exactly the same is true for conjunctions:
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::disjoin_cw</span><buttonclass="popup"onclick="togglePopup('usagePopup18')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup18">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::disjoin_cw</span></span>:<br/><ahref="4-ni.html#SP17">§17</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the case where we have no information about X</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax"> == </span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">) </span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">0</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> and about Y</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">return</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax"> | </span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the general case discussed above</span>
<spanclass="plain-syntax">}</span>
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::disjoin_fw</span><buttonclass="popup"onclick="togglePopup('usagePopup19')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup19">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::disjoin_fw</span></span>:<br/><ahref="4-ni.html#SP17">§17</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::disjoin_fs</span><buttonclass="popup"onclick="togglePopup('usagePopup20')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup20">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::disjoin_fs</span></span>:<br/><ahref="4-ni.html#SP17">§17</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m1</span><spanclass="plain-syntax">, </span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">m2</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP22"></a><b>§22. Range requirement simplification. </b>Once the bitmaps in all the necessary requirements have been made, the following
is used to simplify them — paring down any logical redundancy in them, so
that the simplest possible tests will be applied by <ahref="4-ni.html#SP8"class="internal">NTI::nt_bitmap_violates</a>.
<spanclass="reserved-syntax">void</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::simplify_requirement</span><buttonclass="popup"onclick="togglePopup('usagePopup21')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup21">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::simplify_requirement</span></span>:<br/><ahref="4-ni.html#SP23">§23</a>, <ahref="4-ni.html#SP24">§24</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">nti_constraint</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">ntic</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP22_1"class="named-paragraph-link"><spanclass="named-paragraph">Remove a disjunction test contained in a first-word test</span><spanclass="named-paragraph-number">22.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP22_2"class="named-paragraph-link"><spanclass="named-paragraph">Remove a first-word test contained in a conjunction test</span><spanclass="named-paragraph-number">22.2</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP22_3"class="named-paragraph-link"><spanclass="named-paragraph">Remove a disjunction test contained in a conjunction test</span><spanclass="named-paragraph-number">22.3</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP22_4"class="named-paragraph-link"><spanclass="named-paragraph">Remove any weak test which partially duplicates a strong one</span><spanclass="named-paragraph-number">22.4</span></a></span><spanclass="plain-syntax">;</span>
<pclass="commentary firstcommentary"><aid="SP22_1"></a><b>§22.1. </b>Suppose the NTIC says "one of these words has to have bit X", a disjunction
test, but also "the first word has to have bit X", a first word text. Then we
can get rid of the disjunction test — it is implied by the first word text,
and is both slower and weaker.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Remove a disjunction test contained in a first-word test</span><spanclass="named-paragraph-number">22.1</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP22">§22</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP22_2"></a><b>§22.2. </b>Suppose the NTIC says "every word has to have X" but also "the first word
has to have X". Then we get rid of the first word test, which is implied
and is weaker.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Remove a first-word test contained in a conjunction test</span><spanclass="named-paragraph-number">22.2</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP22">§22</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP22_3"></a><b>§22.3. </b>Now suppose we have both "one of these words has to have X" and also
"all of these words have to have X". We get rid of the "some of" test.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Remove a disjunction test contained in a conjunction test</span><spanclass="named-paragraph-number">22.3</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP22">§22</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP22_4"></a><b>§22.4. </b>Finally suppose we have "a word must have some bits from set A" and
also "a word must have all of the bits from set B", where B is a superset
of A. Then the first, weak, test can go, since it is implied by the strong one.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Remove any weak test which partially duplicates a strong one</span><spanclass="named-paragraph-number">22.4</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP22">§22</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP23"></a><b>§23. </b>The "ditto flag" on a requirement is used when there are two requirements,
here <spanclass="extract"><spanclass="extract-syntax">prev</span></span> then <spanclass="extract"><spanclass="extract-syntax">ntic</span></span>, representing alternatives for parsing the same text —
i.e., it must match either <spanclass="extract"><spanclass="extract-syntax">prev</span></span> or <spanclass="extract"><spanclass="extract-syntax">ntic</span></span>. If these two requirements are
the same, we needn't check the second one after the first has been checked.
So we give <spanclass="extract"><spanclass="extract-syntax">ntic</span></span> the ditto flag, to say "same as the one before".
<spanclass="reserved-syntax">void</span><spanclass="plain-syntax"></span><spanclass="function-syntax">NTI::calculate_constraint</span><buttonclass="popup"onclick="togglePopup('usagePopup24')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup24">Usage of <spanclass="code-font"><spanclass="function-syntax">NTI::calculate_constraint</span></span>:<br/>The Optimiser - <ahref="4-to.html#SP8">§8</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">nonterminal</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">nt</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP25_1"class="named-paragraph-link"><spanclass="named-paragraph">Mark up fixed wording in the grammar for NT with the NT's incidence bit</span><spanclass="named-paragraph-number">25.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP25_2"class="named-paragraph-link"><spanclass="named-paragraph">Calculate requirement for NT</span><spanclass="named-paragraph-number">25.2</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax">}</span>
</pre>
<pclass="commentary firstcommentary"><aid="SP25_1"></a><b>§25.1. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Mark up fixed wording in the grammar for NT with the NT's incidence bit</span><spanclass="named-paragraph-number">25.1</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP25">§25</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP25_2"></a><b>§25.2. </b>The requirement for a NT is a disjunction of the requirements for the productions.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Calculate requirement for NT</span><spanclass="named-paragraph-number">25.2</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP25_2_1"class="named-paragraph-link"><spanclass="named-paragraph">Calculate requirement for production</span><spanclass="named-paragraph-number">25.2.1</span></a></span><spanclass="plain-syntax">;</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="4-ni.html#SP25">§25</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP25_2_1"></a><b>§25.2.1. </b>The requirement for a production is a concatenation of the requirements for the
ptokens.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Calculate requirement for production</span><spanclass="named-paragraph-number">25.2.1</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="4-ni.html#SP25_2_1_1"class="named-paragraph-link"><spanclass="named-paragraph">Calculate requirement for ptoken</span><spanclass="named-paragraph-number">25.2.1.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">empty</span><spanclass="plain-syntax"> = </span><spanclass="identifier-syntax">TRUE</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> even if negated, notice</span>
<ulclass="items"><li>(a) When it starts up, it can call <ahref="4-ni.html#SP27"class="internal">NTI::give_nt_reserved_incidence_bit</a>—
see below — or <ahref="4-nnt.html#SP11"class="internal">Nonterminals::make_numbering</a> or <ahref="4-nnt.html#SP12"class="internal">Nonterminals::flag_words_with</a>.
</li><li>(b) When <ahref="4-to.html"class="internal">The Optimiser</a> runs, it calls two callback functions which have
a chance to add NTI constraints to nonterminals.
</li></ul>
<pclass="commentary firstcommentary"><aid="SP27"></a><b>§27. </b>To take (a) first: as we've seen, each NT is assigned an NTI bit, handed
<pclass="commentary firstcommentary"><aid="SP28"></a><b>§28. </b>Now for opportunity (b). <ahref="index.html"class="internal">words</a> provides for up to two callback functions