1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/14-sp.html
2020-04-07 01:06:09 +01:00

487 lines
62 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>13/ki</title>
<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="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '14/sp' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#14">Chapter 14: Specifications</a></li><li><b>Specifications</b></li></ul><p class="purpose">To create, manage and compare specifications.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Kinds vs specifications</a></li><li><a href="#SP6">&#167;6. Pretty-printing specifications</a></li><li><a href="#SP7">&#167;7. Sorting</a></li><li><a href="#SP8">&#167;8. The Unknown</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Kinds vs specifications. </b>Specifications are portions of the parse tree representing data, or conditions
on data, or ways to manipulate it. This chapter contains utility routines
for creating and using them.
</p>
<p class="inwebparagraph">Kinds can be faithfully represented as specifications, but not vice versa:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Descriptions::from_kind</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">AMBIGUITY_NT</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Descriptions::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lvalues::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_rvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Specifications::to_true_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lvalues::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_rvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Specifications::to_true_kind_disambiguated</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">AMBIGUITY_NT</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">TEST_VALUE_NT</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lvalues::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_rvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::from_kind is used in <a href="#SP5">&#167;5</a>, 4/am (<a href="4-am.html#SP24_6">&#167;24.6</a>), 9/rpt (<a href="9-rpt.html#SP10_1">&#167;10.1</a>), 9/tc (<a href="9-tc.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="9-tc.html#SP5_4_2_1">&#167;5.4.2.1</a>, <a href="9-tc.html#SP5_4_2_4">&#167;5.4.2.4</a>), 9/ma (<a href="9-ma.html#SP3_3_25">&#167;3.3.25</a>, <a href="9-ma.html#SP3_3_41_7">&#167;3.3.41.7</a>), 10/cad (<a href="10-cad.html#SP16">&#167;16</a>), 10/teav (<a href="10-teav.html#SP3">&#167;3</a>), 12/ap (<a href="12-ap.html#SP9_5_2">&#167;9.5.2</a>), 14/ds2 (<a href="14-ds2.html#SP19_3_1">&#167;19.3.1</a>, <a href="14-ds2.html#SP25">&#167;25</a>), 16/is (<a href="16-is.html#SP18">&#167;18</a>), 19/tb (<a href="19-tb.html#SP24_2">&#167;24.2</a>, <a href="19-tb.html#SP24_3">&#167;24.3</a>), 19/tod (<a href="19-tod.html#SP6_3">&#167;6.3</a>), 22/dptd (<a href="22-dptd.html#SP18_1">&#167;18.1</a>, <a href="22-dptd.html#SP19">&#167;19</a>, <a href="22-dptd.html#SP20_3_2">&#167;20.3.2</a>), 25/pi (<a href="25-pi.html#SP4_2">&#167;4.2</a>).</p>
<p class="endnote">The function Specifications::to_kind is used in <a href="#SP5">&#167;5</a>, 2/sq (<a href="2-sq.html#SP4">&#167;4</a>), 4/am (<a href="4-am.html#SP24">&#167;24</a>), 9/rpt (<a href="9-rpt.html#SP9_7_6_3_1">&#167;9.7.6.3.1</a>, <a href="9-rpt.html#SP10_1">&#167;10.1</a>), 9/tc (<a href="9-tc.html#SP4_3">&#167;4.3</a>, <a href="9-tc.html#SP4_4">&#167;4.4</a>, <a href="9-tc.html#SP4_6">&#167;4.6</a>, <a href="9-tc.html#SP5_4_2_2">&#167;5.4.2.2</a>, <a href="9-tc.html#SP8">&#167;8</a>), 9/ma (<a href="9-ma.html#SP3_3_25">&#167;3.3.25</a>, <a href="9-ma.html#SP3_3_26_1">&#167;3.3.26.1</a>, <a href="9-ma.html#SP3_3_34">&#167;3.3.34</a>, <a href="9-ma.html#SP3_3_39">&#167;3.3.39</a>, <a href="9-ma.html#SP3_3_39_1">&#167;3.3.39.1</a>, <a href="9-ma.html#SP3_3_39_5">&#167;3.3.39.5</a>, <a href="9-ma.html#SP3_3_40">&#167;3.3.40</a>, <a href="9-ma.html#SP3_3_40_1">&#167;3.3.40.1</a>, <a href="9-ma.html#SP3_3_41">&#167;3.3.41</a>, <a href="9-ma.html#SP3_3_41_8">&#167;3.3.41.8</a>), 9/pk (<a href="9-pk.html#SP2">&#167;2</a>, <a href="9-pk.html#SP3">&#167;3</a>), 9/pd (<a href="9-pd.html#SP5_6">&#167;5.6</a>), 10/cad (<a href="10-cad.html#SP19_2">&#167;19.2</a>), 11/pr (<a href="11-pr.html#SP23">&#167;23</a>), 11/sm (<a href="11-sm.html#SP12">&#167;12</a>), 11/tcp (<a href="11-tcp.html#SP8">&#167;8</a>), 12/ter (<a href="12-ter.html#SP8_5">&#167;8.5</a>), 12/ap (<a href="12-ap.html#SP12">&#167;12</a>), 12/is (<a href="12-is.html#SP8">&#167;8</a>, <a href="12-is.html#SP9">&#167;9</a>), 12/ca (<a href="12-ca.html#SP6_6">&#167;6.6</a>), 12/dtd (<a href="12-dtd.html#SP10">&#167;10</a>, <a href="12-dtd.html#SP16">&#167;16</a>, <a href="12-dtd.html#SP18">&#167;18</a>, <a href="12-dtd.html#SP23">&#167;23</a>, <a href="12-dtd.html#SP27">&#167;27</a>), 12/cad (<a href="12-cad.html#SP3">&#167;3</a>, <a href="12-cad.html#SP6">&#167;6</a>), 14/rv (<a href="14-rv.html#SP21">&#167;21</a>), 14/lv (<a href="14-lv.html#SP12_4">&#167;12.4</a>, <a href="14-lv.html#SP14_3">&#167;14.3</a>), 14/cn (<a href="14-cn.html#SP12">&#167;12</a>), 14/ds (<a href="14-ds.html#SP11">&#167;11</a>), 14/cfs (<a href="14-cfs.html#SP7">&#167;7</a>, <a href="14-cfs.html#SP8">&#167;8</a>), 14/ds2 (<a href="14-ds2.html#SP10_1_1_3_1">&#167;10.1.1.3.1</a>, <a href="14-ds2.html#SP11_6">&#167;11.6</a>, <a href="14-ds2.html#SP11_9_1_1_3_1_1">&#167;11.9.1.1.3.1.1</a>, <a href="14-ds2.html#SP11_9_1_1_4">&#167;11.9.1.1.4</a>, <a href="14-ds2.html#SP11_9_1_1_5">&#167;11.9.1.1.5</a>, <a href="14-ds2.html#SP11_9_1_1_5_2">&#167;11.9.1.1.5.2</a>, <a href="14-ds2.html#SP11_9_1_2_2">&#167;11.9.1.2.2</a>, <a href="14-ds2.html#SP11_9_1_2_3">&#167;11.9.1.2.3</a>, <a href="14-ds2.html#SP11_9_1_2_3_3">&#167;11.9.1.2.3.3</a>, <a href="14-ds2.html#SP11_9_1_2_4">&#167;11.9.1.2.4</a>, <a href="14-ds2.html#SP13">&#167;13</a>, <a href="14-ds2.html#SP14_1_1">&#167;14.1.1</a>, <a href="14-ds2.html#SP19_5_1">&#167;19.5.1</a>, <a href="14-ds2.html#SP19_5_3">&#167;19.5.3</a>, <a href="14-ds2.html#SP19_5_4">&#167;19.5.4</a>, <a href="14-ds2.html#SP19_6_1">&#167;19.6.1</a>, <a href="14-ds2.html#SP19_6_1_1">&#167;19.6.1.1</a>, <a href="14-ds2.html#SP19_6_2_1">&#167;19.6.2.1</a>, <a href="14-ds2.html#SP25">&#167;25</a>, <a href="14-ds2.html#SP27">&#167;27</a>), 16/is (<a href="16-is.html#SP17">&#167;17</a>), 16/in (<a href="16-in.html#SP14">&#167;14</a>), 18/lc (<a href="18-lc.html#SP8_1">&#167;8.1</a>), 19/tb (<a href="19-tb.html#SP25">&#167;25</a>, <a href="19-tb.html#SP25_1">&#167;25.1</a>), 19/tod (<a href="19-tod.html#SP6_1">&#167;6.1</a>), 20/eq (<a href="20-eq.html#SP18_1">&#167;18.1</a>), 21/rl2 (<a href="21-rl2.html#SP14">&#167;14</a>), 21/ac (<a href="21-ac.html#SP8">&#167;8</a>), 22/dptd (<a href="22-dptd.html#SP3_1_2_1">&#167;3.1.2.1</a>, <a href="22-dptd.html#SP20_2_1">&#167;20.2.1</a>), 24/lv (<a href="24-lv.html#SP34">&#167;34</a>), 25/pi (<a href="25-pi.html#SP4_2">&#167;4.2</a>, <a href="25-pi.html#SP5">&#167;5</a>, <a href="25-pi.html#SP5_2">&#167;5.2</a>), 25/ci (<a href="25-ci.html#SP3_1_1_1">&#167;3.1.1.1</a>, <a href="25-ci.html#SP3_2_3_1_1">&#167;3.2.3.1.1</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_7_1">&#167;3.1.1.4.7.1</a>, <a href="25-cii.html#SP3_5_3">&#167;3.5.3</a>, <a href="25-cii.html#SP3_5_4">&#167;3.5.4</a>, <a href="25-cii.html#SP3_5_7_1">&#167;3.5.7.1</a>, <a href="25-cii.html#SP3_5_8_1">&#167;3.5.8.1</a>, <a href="25-cii.html#SP3_7_1">&#167;3.7.1</a>, <a href="25-cii.html#SP7">&#167;7</a>), 25/cp (<a href="25-cp.html#SP5_3_5">&#167;5.3.5</a>), 26/ts (<a href="26-ts.html#SP11">&#167;11</a>, <a href="26-ts.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Specifications::to_true_kind appears nowhere else.</p>
<p class="endnote">The function Specifications::to_true_kind_disambiguated is used in 14/rv (<a href="14-rv.html#SP17">&#167;17</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>We say that a specification is "kind-like" if it's one of those which could
result from <code class="display"><span class="extract">Specifications::from_kind</span></code>: for example, the description "numbers"
is kind-like, but "even numbers" is not.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Descriptions::is_kind_like</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::is_kind_like is used in <a href="#SP5">&#167;5</a>, 9/tc (<a href="9-tc.html#SP4_3">&#167;4.3</a>, <a href="9-tc.html#SP8">&#167;8</a>), 9/ma (<a href="9-ma.html#SP3_3_26">&#167;3.3.26</a>, <a href="9-ma.html#SP3_3_26_1">&#167;3.3.26.1</a>, <a href="9-ma.html#SP3_3_39">&#167;3.3.39</a>, <a href="9-ma.html#SP3_3_41_5">&#167;3.3.41.5</a>), 14/ds2 (<a href="14-ds2.html#SP11_4_1">&#167;11.4.1</a>, <a href="14-ds2.html#SP11_8_1">&#167;11.8.1</a>, <a href="14-ds2.html#SP11_9_1_1_3_1_1">&#167;11.9.1.1.3.1.1</a>, <a href="14-ds2.html#SP14_1_1">&#167;14.1.1</a>, <a href="14-ds2.html#SP19_6_2_1">&#167;19.6.2.1</a>), 15/pr (<a href="15-pr.html#SP5_2">&#167;5.2</a>), 16/is (<a href="16-is.html#SP17">&#167;17</a>), 19/tb (<a href="19-tb.html#SP25_2">&#167;25.2</a>), 19/rsft (<a href="19-rsft.html#SP1_1_1_1_1_4">&#167;1.1.1.1.1.4</a>), 19/tod (<a href="19-tod.html#SP6_1">&#167;6.1</a>, <a href="19-tod.html#SP6_3">&#167;6.3</a>), 21/ac (<a href="21-ac.html#SP8">&#167;8</a>), 22/dptd (<a href="22-dptd.html#SP3_1_2_1">&#167;3.1.2.1</a>), 24/lv (<a href="24-lv.html#SP33_2">&#167;33.2</a>, <a href="24-lv.html#SP34">&#167;34</a>), 25/pi (<a href="25-pi.html#SP4_2">&#167;4.2</a>, <a href="25-pi.html#SP5">&#167;5</a>, <a href="25-pi.html#SP5_2">&#167;5.2</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Another useful characterisation is "description-like". Most nouns are not
description-like, but names of objects are. Thus "Mrs Jones" is description-like,
but "12" is not.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Specifications::is_description_like</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">g</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)) </span><span class="identifier">g</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_object</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)) </span><span class="identifier">g</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_nothing_object_constant</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)) </span><span class="identifier">g</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">g</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">TEST_VALUE_NT</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="identifier">CON_description</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Descriptions::to_proposition</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_proposition</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::is_description_like is used in 4/am (<a href="4-am.html#SP24_4">&#167;24.4</a>), 10/varc (<a href="10-varc.html#SP4_2">&#167;4.2</a>, <a href="10-varc.html#SP9_1">&#167;9.1</a>), 11/sc (<a href="11-sc.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Specifications::is_description is used in <a href="#SP1">&#167;1</a>, <a href="#SP4">&#167;4</a>, <a href="#SP7">&#167;7</a>, 9/rpt (<a href="9-rpt.html#SP9_7_6">&#167;9.7.6</a>), 9/tc (<a href="9-tc.html#SP4_6">&#167;4.6</a>), 9/ma (<a href="9-ma.html#SP3_3_26">&#167;3.3.26</a>, <a href="9-ma.html#SP3_3_39">&#167;3.3.39</a>), 9/pk (<a href="9-pk.html#SP3">&#167;3</a>, <a href="9-pk.html#SP3_2">&#167;3.2</a>), 9/pd (<a href="9-pd.html#SP5_8_1">&#167;5.8.1</a>, <a href="9-pd.html#SP5_8_3">&#167;5.8.3</a>, <a href="9-pd.html#SP5_11_1">&#167;5.11.1</a>, <a href="9-pd.html#SP7_1_1_1">&#167;7.1.1.1</a>), 10/cad (<a href="10-cad.html#SP19_3">&#167;19.3</a>), 10/varc (<a href="10-varc.html#SP13_4_1">&#167;13.4.1</a>), 11/pr (<a href="11-pr.html#SP35">&#167;35</a>), 12/ap (<a href="12-ap.html#SP12">&#167;12</a>), 14/cn (<a href="14-cn.html#SP12">&#167;12</a>, <a href="14-cn.html#SP13">&#167;13</a>, <a href="14-cn.html#SP16">&#167;16</a>), 14/ds (<a href="14-ds.html#SP1">&#167;1</a>, <a href="14-ds.html#SP2">&#167;2</a>, <a href="14-ds.html#SP4">&#167;4</a>, <a href="14-ds.html#SP5">&#167;5</a>, <a href="14-ds.html#SP6">&#167;6</a>, <a href="14-ds.html#SP7">&#167;7</a>, <a href="14-ds.html#SP9">&#167;9</a>, <a href="14-ds.html#SP10">&#167;10</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_3_1_1">&#167;11.9.1.1.3.1.1</a>, <a href="14-ds2.html#SP11_9_1_2_3">&#167;11.9.1.2.3</a>, <a href="14-ds2.html#SP19_5_3">&#167;19.5.3</a>, <a href="14-ds2.html#SP19_6_2">&#167;19.6.2</a>, <a href="14-ds2.html#SP25">&#167;25</a>), 15/pr (<a href="15-pr.html#SP5_2">&#167;5.2</a>), 19/tb (<a href="19-tb.html#SP25_2">&#167;25.2</a>), 19/tod (<a href="19-tod.html#SP6_1">&#167;6.1</a>), 21/rl2 (<a href="21-rl2.html#SP14">&#167;14</a>), 21/ac (<a href="21-ac.html#SP8">&#167;8</a>, <a href="21-ac.html#SP14">&#167;14</a>), 22/dptd (<a href="22-dptd.html#SP3_1_2_1">&#167;3.1.2.1</a>), 24/lv (<a href="24-lv.html#SP34">&#167;34</a>), 25/pi (<a href="25-pi.html#SP4_2">&#167;4.2</a>, <a href="25-pi.html#SP5_2">&#167;5.2</a>), 25/ci (<a href="25-ci.html#SP3_2_3_4_1_1_1">&#167;3.2.3.4.1.1.1</a>).</p>
<p class="endnote">The function Specifications::to_proposition is used in 9/rpt (<a href="9-rpt.html#SP1">&#167;1</a>, <a href="9-rpt.html#SP9_7_6_3_1">&#167;9.7.6.3.1</a>), 9/tc (<a href="9-tc.html#SP5_2_1">&#167;5.2.1</a>), 9/ma (<a href="9-ma.html#SP3_3_8">&#167;3.3.8</a>), 9/pk (<a href="9-pk.html#SP3_2">&#167;3.2</a>), 10/varc (<a href="10-varc.html#SP13_3">&#167;13.3</a>), 11/pr (<a href="11-pr.html#SP35">&#167;35</a>), 11/sc (<a href="11-sc.html#SP3">&#167;3</a>), 12/dtd (<a href="12-dtd.html#SP6">&#167;6</a>, <a href="12-dtd.html#SP18">&#167;18</a>, <a href="12-dtd.html#SP23">&#167;23</a>), 14/cn (<a href="14-cn.html#SP13">&#167;13</a>, <a href="14-cn.html#SP15">&#167;15</a>, <a href="14-cn.html#SP16">&#167;16</a>), 14/ds (<a href="14-ds.html#SP1">&#167;1</a>), 14/ds2 (<a href="14-ds2.html#SP19_4">&#167;19.4</a>), 19/tod (<a href="19-tod.html#SP6_1_2">&#167;6.1.2</a>), 24/ch (<a href="24-ch.html#SP7_4_1">&#167;7.4.1</a>), 25/cp (<a href="25-cp.html#SP5_3_2">&#167;5.3.2</a>), 26/ts (<a href="26-ts.html#SP11_1">&#167;11.1</a>, <a href="26-ts.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Specifications which talk about objects lie in two different families:
"Mrs Jones" is a CONSTANT with kind "object", but "the open Bronze Gateway"
is a DESCRIPTION. The following extracts the object, if any, from either case:
</p>
<pre class="display">
<span class="reserved">instance</span><span class="plain"> *</span><span class="functiontext">Specifications::object_exactly_described_if_any</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Descriptions::to_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_object</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_nothing_object_constant</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::object_exactly_described_if_any is used in <a href="#SP7">&#167;7</a>, 19/tod (<a href="19-tod.html#SP6_1">&#167;6.1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>It's convenient to use specifications to represent the requirement on a
new variable declaration, such as that in "The tally is a number that varies."
We do this with the kind-like specification for "K that varies". Such a node
is called "new-variable-like".
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Specifications::new_new_variable_like</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_variable</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Specifications::kind_of_new_variable_like</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Specifications::is_new_variable_like</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) == </span><span class="identifier">CON_variable</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::new_new_variable_like is used in 10/teav (<a href="10-teav.html#SP5">&#167;5</a>, <a href="10-teav.html#SP5_1">&#167;5.1</a>, <a href="10-teav.html#SP5_2">&#167;5.2</a>).</p>
<p class="endnote">The function Specifications::kind_of_new_variable_like is used in 9/tc (<a href="9-tc.html#SP4_3">&#167;4.3</a>, <a href="9-tc.html#SP5_4_2_2">&#167;5.4.2.2</a>), 9/ma (<a href="9-ma.html#SP3_3_39">&#167;3.3.39</a>, <a href="9-ma.html#SP3_3_39_1">&#167;3.3.39.1</a>).</p>
<p class="endnote">The function Specifications::is_new_variable_like is used in 9/tc (<a href="9-tc.html#SP4_3">&#167;4.3</a>, <a href="9-tc.html#SP5_4_2">&#167;5.4.2</a>, <a href="9-tc.html#SP5_4_2_2">&#167;5.4.2.2</a>), 9/ma (<a href="9-ma.html#SP3_3_38_1">&#167;3.3.38.1</a>, <a href="9-ma.html#SP3_3_38_2">&#167;3.3.38.2</a>, <a href="9-ma.html#SP3_3_39">&#167;3.3.39</a>, <a href="9-ma.html#SP3_3_39_1">&#167;3.3.39.1</a>), 9/pd (<a href="9-pd.html#SP7_1_1_1">&#167;7.1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Pretty-printing specifications. </b>We need to be able to print legible forms of translations in order to
produce good error messages, and also in order to describe phrases in the
Index; those have to be English language forms.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"something unknown"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="functiontext">Lvalues::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_rvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="functiontext">Rvalues::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_condition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="functiontext">Conditions::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">AMBIGUITY_NT</span><span class="plain">)) </span><span class="functiontext">Specifications::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"something unrecognised"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::write_out_in_English is used in 2/sq (<a href="2-sq.html#SP1">&#167;1</a>), 22/dptd (<a href="22-dptd.html#SP3_1_2_1">&#167;3.1.2.1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Sorting. </b>Some specifications are used to describe the applicability of rules and phrases,
and since those must be sorted in order of how specific they are, we will need
a way of telling when one specification is more specific than another. For
instance, "Will Parker in the vineyard" beats "Will Parker" beats
"a man" beats "a person" beats "an object" beats "a value".
</p>
<p class="inwebparagraph">The following is one of Inform's standardised comparison routines, which
takes a pair of objects A, B and returns 1 if A makes a more specific
description than B, 0 if they seem equally specific, or -1 if B makes a
more specific description than A. This is transitive, and intended to be
used in sorting algorithms.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cco</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="comment">comparison count: used to make the debugging log vaguely searchable</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">c_s_stage_law</span><span class="plain"> = </span><span class="string">""</span><span class="plain">; </span><span class="comment">name of the law being applied, which caused this to be called</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Specifications::compare_specificity</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec1</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec2</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">wont_mix</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">SPECIFICITIES</span><span class="plain">, </span><span class="string">"Law %s (test %d): comparing $P with $P\n"</span><span class="plain">,</span>
<span class="identifier">c_s_stage_law</span><span class="plain">, </span><span class="identifier">cco</span><span class="plain">++, </span><span class="identifier">spec1</span><span class="plain">, </span><span class="identifier">spec2</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Existence is itself something specific</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">a</span><span class="plain"> = </span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">),</span>
<span class="identifier">b</span><span class="plain"> = </span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I1</span><span class="plain"> = </span><span class="functiontext">Specifications::object_exactly_described_if_any</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I2</span><span class="plain"> = </span><span class="functiontext">Specifications::object_exactly_described_if_any</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
&lt;<span class="cwebmacro">An actual specification is more specific than a generic one</span> <span class="cwebmacronumber">7.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">An exact object is more specific than a vague one</span> <span class="cwebmacronumber">7.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I1</span><span class="plain">) </span>&lt;<span class="cwebmacro">Enclosing regions beat enclosed ones, and regions beat rooms</span> <span class="cwebmacronumber">7.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wont_mix</span><span class="plain">) </span>&lt;<span class="cwebmacro">If one matches the other, but not vice versa, it must be more specific</span> <span class="cwebmacronumber">7.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">a</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">b</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">)) { </span><span class="comment">case 1: both are descriptions</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Descriptions::compare_specificity</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">, </span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">a</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">b</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) { </span><span class="comment">case 2: neither is a description</span>
&lt;<span class="cwebmacro">Table entries are more specific than other non-descriptions</span> <span class="cwebmacronumber">7.6</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> { </span><span class="comment">case 3: one is a description, the other isn't</span>
&lt;<span class="cwebmacro">When is a description more specific than a non-description?</span> <span class="cwebmacronumber">7.7</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::compare_specificity is used in 22/prcd (<a href="22-prcd.html#SP8_3">&#167;8.3</a>), 22/ptd (<a href="22-ptd.html#SP21_5_2">&#167;21.5.2</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>Whether or not, as Bertrand Russell thought in 1894, existence is itself a good
("Great God in Boots! Э the ontological argument is sound!"), a specification
which exists is certainly more significant than one which does not; and there
is nothing to choose between two specifications, neither of which exists.
</p>
<p class="inwebparagraph">A God who wears boots is an incongruous thought. Sandals, possibly. But maybe
Russell meant the local Cambridge branch of Boots, the chemist's shop. At any
rate he changed his mind in 1896.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Existence is itself something specific</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">spec1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">spec2</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">spec1</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">spec2</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">spec1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">spec2</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_2"></a><b>&#167;7.2. </b>Hard to argue with this one: "34", for instance, is more specific than
"a number". (We might quibble about whether or not "a number which equals
34" is really less specific than "34" &mdash; Inform says it is; but in fact
it doesn't much matter either way.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">An actual specification is more specific than a generic one</span> <span class="cwebmacronumber">7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">aa</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">a</span><span class="plain">) &amp;&amp; (</span><span class="identifier">I1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">aa</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ba</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">b</span><span class="plain">) &amp;&amp; (</span><span class="identifier">I2</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">ba</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">aa</span><span class="plain">) &amp;&amp; (!</span><span class="identifier">ba</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((!</span><span class="identifier">aa</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ba</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> -1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_3"></a><b>&#167;7.3. </b>For instance, "the open Marble Door" is more specific than "an open door"
or even just "a door", even though the latter is linguistically simpler.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">An exact object is more specific than a vague one</span> <span class="cwebmacronumber">7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">I1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">I2</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">I1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">I2</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> -1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_4"></a><b>&#167;7.4. </b>Suppose both specifications exactly describe objects, <code class="display"><span class="extract">I1</span></code> and <code class="display"><span class="extract">I2</span></code>, and
all other considerations are equal. It's not quite true that one object is as
good as another, because a region can be thought of as a set of rooms.
(Without the following criterion, rules such as "After waiting in Russia"
and "After waiting in Vladivostok Railway Station Waiting Room" would have
equal status.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Enclosing regions beat enclosed ones, and regions beat rooms</span> <span class="cwebmacronumber">7.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">SPECIFICITIES</span><span class="plain">, </span><span class="string">"Test %d: Comparing specificity of instances $O and $O\n"</span><span class="plain">,</span>
<span class="identifier">cco</span><span class="plain">, </span><span class="identifier">I1</span><span class="plain">, </span><span class="identifier">I2</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pref</span><span class="plain"> = </span><span class="functiontext">Plugins::Call::more_specific</span><span class="plain">(</span><span class="identifier">I1</span><span class="plain">, </span><span class="identifier">I2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pref</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">pref</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_5"></a><b>&#167;7.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">If one matches the other, but not vice versa, it must be more specific</span> <span class="cwebmacronumber">7.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ev1</span><span class="plain"> = ((</span><span class="identifier">a</span><span class="plain">) || (</span><span class="functiontext">ParseTreeUsage::is_value</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">)));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ev2</span><span class="plain"> = ((</span><span class="identifier">b</span><span class="plain">) || (</span><span class="functiontext">ParseTreeUsage::is_value</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">)));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">) == </span><span class="constant">PROPERTY_VALUE_NT</span><span class="plain">) </span><span class="identifier">ev1</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">) == </span><span class="constant">PROPERTY_VALUE_NT</span><span class="plain">) </span><span class="identifier">ev2</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ev1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ev2</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> = </span><span class="functiontext">Dash::compatible_with_description</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">, </span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">y</span><span class="plain"> = </span><span class="functiontext">Dash::compatible_with_description</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">, </span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> == </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">y</span><span class="plain"> == </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">y</span><span class="plain"> == </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> == </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wont_mix</span><span class="plain">) *</span><span class="identifier">wont_mix</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_6"></a><b>&#167;7.6. </b>Here neither specification is a description or an actual object.
For the most part, then, we're left with two specifications of about equal
merit, and we don't choose between them. But in one case we do intervene: a
table entry reference beats anything else left, so that "Instead of taking
the magic key corresponding to Merlin in the Table of Arcana" is more
specific than "Instead of taking the brass key". It's questionable whether
this is a good convention, but users reported the previous absence of such
a convention as a bug, which is usually telling.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Table entries are more specific than other non-descriptions</span> <span class="cwebmacronumber">7.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t1</span><span class="plain"> = </span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">, </span><span class="constant">TABLE_ENTRY_NT</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t2</span><span class="plain"> = </span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">, </span><span class="constant">TABLE_ENTRY_NT</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t1</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">t2</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t1</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">t2</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> -1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_7"></a><b>&#167;7.7. </b>To explicate the following: a description of an exact object beats any
non-description &mdash; thus "the open Marble Door" (a description) beats "the
Marble Door" (a constant instance). But any non-description beats a
description which is vague about the object &mdash; thus "the Marble Door" beats
"an open door", which is not news since rules above would enact that anyway,
but also "the tallest door in the Castle" (a phrase) beats "an open door".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">When is a description more specific than a non-description?</span> <span class="cwebmacronumber">7.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I1</span><span class="plain">) { </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">a</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> -1; }</span>
<span class="reserved">else</span><span class="plain"> { </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">a</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1; </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">; }</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. The Unknown. </b>We begin with s-nodes used to represent text not yet parsed, or for which no
meaning could be found.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">UNKNOWN_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::new_UNKNOWN is used in 5/nv (<a href="5-nv.html#SP17">&#167;17</a>), 9/rpt (<a href="9-rpt.html#SP9_7_6_3">&#167;9.7.6.3</a>), 10/aots (<a href="10-aots.html#SP1">&#167;1</a>, <a href="10-aots.html#SP2">&#167;2</a>, <a href="10-aots.html#SP13">&#167;13</a>), 10/cad (<a href="10-cad.html#SP19_3">&#167;19.3</a>, <a href="10-cad.html#SP21">&#167;21</a>), 10/teav (<a href="10-teav.html#SP13">&#167;13</a>, <a href="10-teav.html#SP22">&#167;22</a>), 10/varc (<a href="10-varc.html#SP13">&#167;13</a>, <a href="10-varc.html#SP13_4_1">&#167;13.4.1</a>), 14/rv (<a href="14-rv.html#SP17">&#167;17</a>), 14/ds (<a href="14-ds.html#SP6">&#167;6</a>), 18/lc (<a href="18-lc.html#SP4">&#167;4</a>), 19/tb (<a href="19-tb.html#SP24_1">&#167;24.1</a>), 21/ac (<a href="21-ac.html#SP6">&#167;6</a>, <a href="21-ac.html#SP10_1">&#167;10.1</a>, <a href="21-ac.html#SP10_6">&#167;10.6</a>), 25/pi (<a href="25-pi.html#SP4_2">&#167;4.2</a>, <a href="25-pi.html#SP5_2">&#167;5.2</a>), 25/cii (<a href="25-cii.html#SP8">&#167;8</a>), 25/cp (<a href="25-cp.html#SP5_3_2">&#167;5.3.2</a>), 26/ts (<a href="26-ts.html#SP11">&#167;11</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 14: Specifications.)</i></li><li><a href="14-rv.html">Continue with 'RValues'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>