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/19-tod.html
2019-04-22 15:42:10 +01:00

759 lines
76 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>19/rsft</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '19/tod' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#19">Chapter 19: Table Data</a></li><li><b>Tables of Definitions</b></li></ul><p class="purpose">To support tables which amount to massed groups of assertions.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Kinds defined by table</a></li><li><a href="#SP3">&#167;3. Handling definition-by-table sentences</a></li><li><a href="#SP6_3">&#167;6.3. Name creation</a></li><li><a href="#SP6_4">&#167;6.4. Property assignment</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Kinds defined by table. </b>Tables lie behind the special "defined by" sentence. These come in three
subtly different versions:
</p>
<blockquote>
<p>[1] Some animals are defined by the Table of Specimens.</p>
</blockquote>
<blockquote>
<p>[2] Some men in the Zoo are defined by the Table of Zookeepers.</p>
</blockquote>
<blockquote>
<p>[3] Some kinds of animal are defined by the Table of Zoology.</p>
</blockquote>
<p class="inwebparagraph">The subject in [1] is the name of a kind; in [2], it's a description which
incorporates a kind, but can include relative clauses and adjectives; in [3],
it's something second-order &mdash; a kind of a kind. Given this variety of
possibilities, we treat "defined by" sentences as if they were abbreviations
for a mass of assertion sentences, one for each row of the table. We do
however reject:
</p>
<blockquote>
<p>The okapi is defined by the Table of Short-Necked Giraffes.</p>
</blockquote>
<p class="inwebparagraph">where the "okapi" is an existing single animal (or indeed where it's a new
name, meaning as yet unknown).
</p>
<p class="inwebparagraph">The subject must match:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">defined</span><span class="plain">-</span><span class="identifier">by</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">subject</span><span class="plain">&gt; ::=</span>
<span class="identifier">kind</span><span class="plain">/</span><span class="identifier">kinds</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_TableDefiningTheImpossible problem</span> <span class="cwebmacronumber">1.1</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_TableDefiningTheImpossible problem</span> <span class="cwebmacronumber">1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Actually issue PM_TableDefiningTheImpossible problem</span> <span class="cwebmacronumber">1.1.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_1_1"></a><b>&#167;1.1.1. </b>(We're going to need this twice.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Actually issue PM_TableDefiningTheImpossible problem</span> <span class="cwebmacronumber">1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableDefiningTheImpossible</span><span class="plain">),</span>
<span class="string">"you can only use 'defined by' to set up values and things"</span><span class="plain">,</span>
<span class="string">"as created with sentences like 'The tree species are defined by Table 1.' "</span>
<span class="string">"or 'Some men are defined by the Table of Eligible Bachelors.'"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1_1">&#167;1.1</a>, <a href="#SP6_1">&#167;6.1</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>And the object, which in fact is required to be a table name value:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">defined</span><span class="plain">-</span><span class="identifier">by</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Allow if a table name</span> <span class="cwebmacronumber">2.1</span>&gt;
<span class="plain">... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_TableUndefined problem</span> <span class="cwebmacronumber">2.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Allow if a table name</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1];</span>
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">K_table</span><span class="plain">)))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_2"></a><b>&#167;2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_TableUndefined problem</span> <span class="cwebmacronumber">2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableUndefined</span><span class="plain">),</span>
<span class="string">"you can only use 'defined by' in terms of a table"</span><span class="plain">,</span>
<span class="string">"which lists the value names in the first column."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Handling definition-by-table sentences. </b>The timing of when to act on defined-by sentences is not completely
straightforward; if it's wrong, entries making cross-references may sometimes
be rejected by Inform for what seem very opaque reasons. Here's the timeline:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Inform looks for tables in the source text, creating the table names
and columns, though it doesn't know the column kinds yet. (The point of
this is to make sure table column names are in place before properties
begin to be used in assertion sentence, since these names can overlap.)
</li></ul>
<ul class="items"><li>(b) Main assertion traverse 1: Nothing is done with most tables, but with
defined-by tables, the names in column 1 are created, and their identities
are asserted.
</li></ul>
<ul class="items"><li>(c) All tables are "stocked", a process which involves parsing their cell
values. This finally settles the kind of any columns where this has to be
inferred from the contents.
</li></ul>
<ul class="items"><li>(d) Main assertion traverse 2: Nothing is done with most tables, but with
defined-by tables, property values in columns 2 onwards are assigned to
whatever is named in column 1.
</li></ul>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>So this handles the special meaning "X is defined by Y".
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">defined</span><span class="plain">-</span><span class="identifier">by</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ::=</span>
<span class="identifier">defined</span><span class="plain"> </span><span class="identifier">by</span><span class="plain"> &lt;</span><span class="identifier">nounphrase</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt; ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Tables::Defining::defined_by_SMF</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">NPs</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[0]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">OW</span><span class="plain"> = (</span><span class="identifier">NPs</span><span class="plain">)?(</span><span class="identifier">NPs</span><span class="plain">[1]):</span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">task</span><span class="plain">) { </span> <span class="comment">"The colours are defined by Table 1."</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">ACCEPT_SMFT</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">defined</span><span class="plain">-</span><span class="identifier">by</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">&gt;(</span><span class="identifier">OW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">FALSE</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="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">, </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="constant">examine_for_ofs_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">O</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="plain">&lt;</span><span class="identifier">nounphrase</span><span class="plain">&gt;(</span><span class="identifier">SW</span><span class="plain">);</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">O</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TRAVERSE1_SMFT</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TRAVERSE2_SMFT</span><span class="plain">:</span>
<span class="functiontext">Tables::Defining::kind_defined_by_table</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::Defining::defined_by_SMF is used in 6/nv (<a href="6-nv.html#SP16">&#167;16</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Stages (a) and (c) above are both handled by the following routine,
which is called on "defined by" sentences, and thus is never called in
connection with ordinary tables.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::Defining::kind_defined_by_table</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">LTW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SPW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Traverse %d: I now want to define &lt;%W&gt; by table &lt;%W&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">traverse</span><span class="plain">, </span><span class="identifier">SPW</span><span class="plain">, </span><span class="identifier">LTW</span><span class="plain">);</span>
<span class="plain">&lt;</span><span class="identifier">defined</span><span class="plain">-</span><span class="identifier">by</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt;(</span><span class="identifier">LTW</span><span class="plain">); </span><span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_table</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == 1) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">abstract</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</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">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Decide whether this will be an abstract or a concrete creation</span> <span class="cwebmacronumber">6.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check that this is a kind where it makes sense to enumerate new values</span> <span class="cwebmacronumber">6.2</span>&gt;<span class="plain">;</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">Kinds::weaken</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))) </span><span class="functiontext">Tables::Defining::set_defined_by_table</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;kind_defined_in_this_table</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="functiontext">Tables::Columns::set_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[0]</span><span class="element">.column_identity</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Create values for this kind as enumerated by names in the first column</span> <span class="cwebmacronumber">6.3</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Assign properties for these values as enumerated in subsequent columns</span> <span class="cwebmacronumber">6.4</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::Defining::kind_defined_by_table is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP6_1"></a><b>&#167;6.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Decide whether this will be an abstract or a concrete creation</span> <span class="cwebmacronumber">6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">&lt;</span><span class="identifier">defined</span><span class="plain">-</span><span class="identifier">by</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">subject</span><span class="plain">&gt;(</span><span class="identifier">SPW</span><span class="plain">); </span><span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">what</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</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">what</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">what</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">abstract</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">abstract</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;contains_property_values_at_run_time</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;fill_in_blanks</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;preserve_row_order_at_run_time</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;disable_block_constant_correction</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::object_exactly_described_if_any</span><span class="plain">(</span><span class="identifier">what</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Issue PM_TableDefiningObject problem</span> <span class="cwebmacronumber">6.1.1</span>&gt;
<span class="reserved">return</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="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">what</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Check that this is a description which in principle can be asserted</span> <span class="cwebmacronumber">6.1.2</span>&gt;<span class="plain">;</span>
<span class="identifier">abstract</span><span class="plain"> = </span><span class="identifier">FALSE</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">what</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Error at: $T"</span><span class="plain">, </span><span class="identifier">what</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Actually issue PM_TableDefiningTheImpossible problem</span> <span class="cwebmacronumber">1.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t</span><span class="plain">) &amp;&amp; (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;has_been_amended</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableCantDefineAndAmend</span><span class="plain">),</span>
<span class="string">"you can't use 'defined by' to define objects using a table "</span>
<span class="string">"which is amended by another table"</span><span class="plain">,</span>
<span class="string">"since that could too easily lead to ambiguities about what "</span>
<span class="string">"the property values are."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;first_column_by_definition</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;where_used_to_define</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_1_1"></a><b>&#167;6.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_TableDefiningObject problem</span> <span class="cwebmacronumber">6.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableDefiningObject</span><span class="plain">),</span>
<span class="string">"you can only use 'defined by' to set up values and things"</span><span class="plain">,</span>
<span class="string">"as created with sentences like 'The tree species are defined by Table 1.' "</span>
<span class="string">"or 'Some men are defined by the Table of Eligible Bachelors.' - trying to "</span>
<span class="string">"define a single specific object, as here, is not allowed."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_1">&#167;6.1</a>.</p>
<p class="inwebparagraph"><a id="SP6_2"></a><b>&#167;6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that this is a kind where it makes sense to enumerate new values</span> <span class="cwebmacronumber">6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Behaviour::has_named_constant_values</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="identifier">LOG</span><span class="plain">(</span><span class="string">"K is $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableOfBuiltInKind</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but this would mean making each of the names in "</span>
<span class="string">"the first column %2 that's new. This is a kind which can't have "</span>
<span class="string">"entirely new values, so I can't make these definitions."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Behaviour::has_named_constant_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Behaviour::is_uncertainly_defined</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="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableOfExistingKind</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but this would mean making each of the names in "</span>
<span class="string">"the first column %2 that's new. That looks reasonable, since this is a "</span>
<span class="string">"kind which does have named values, but one of the restrictions on "</span>
<span class="string">"definitions-by-table is that all of the values of the kind have "</span>
<span class="string">"to be made by the table: you can't have some defined in ordinary "</span>
<span class="string">"sentences and others in the table."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_1_2"></a><b>&#167;6.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that this is a description which in principle can be asserted</span> <span class="cwebmacronumber">6.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Propositions::contains_quantifier</span><span class="plain">(</span>
<span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">what</span><span class="plain">))) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableOfQuantifiedKind</span><span class="plain">),</span>
<span class="string">"you can't use 'defined by' a table while also talking about the "</span>
<span class="string">"number of things to be defined"</span><span class="plain">,</span>
<span class="string">"since that could too easily lead to contradictions. (So 'Six doors are "</span>
<span class="string">"defined by the Table of Portals' is not allowed - suppose there are ten "</span>
<span class="string">"rows in the Table, making ten doors?)"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_1">&#167;6.1</a>.</p>
<p class="inwebparagraph"><a id="SP6_3"></a><b>&#167;6.3. Name creation. </b>The following code has a curious history: it has evolved backwards from
something much higher-level. When definition by tables began, it was a device
to create new instances &mdash; the names in column 1 would be, say, the instances
of the kind "colour". Inform did this by writing propositions to assert their
existence, in an elegantly high-level way; and all was well. But people also
wanted things like this:
</p>
<blockquote>
<p>Some people on the dais are defined by the Table of Presenters.</p>
</blockquote>
<p class="inwebparagraph">and the process of converting that to propositional form, while issuing
a range of intelligible problem messages if anything went wrong, would end
up duplicating what's already done in the assertion parser.
</p>
<p class="inwebparagraph">So Inform now handles rows in defined-by tables by handing them over to
the assertions system directly. If the name N is in column 1, and the
original sentence read "D are defined by...", then Inform calls the
assertion-maker on the parse tree nodes for N and D exactly as if the
user had written "N is D". Since this explicitly changes the meaning of N
(that's the point), we then re-parse N, and check that it does now refer
to an instance or kind; if it doesn't, then some assertion problem must
have occurred, but if it does then the creation has worked.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Create values for this kind as enumerated by names in the first column</span> <span class="cwebmacronumber">6.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">name_entry</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">objections</span><span class="plain"> = 0, </span><span class="identifier">blank_objections</span><span class="plain"> = 0, </span><span class="identifier">row_count</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">name_entry</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">row_count</span><span class="plain"> = 1; </span><span class="identifier">name_entry</span><span class="plain">;</span>
<span class="identifier">name_entry</span><span class="plain">=</span><span class="identifier">name_entry</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="identifier">row_count</span><span class="plain">++) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"So I want to create: &lt;%W&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">NW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">-</span><span class="identifier">blank</span><span class="plain">&gt;(</span><span class="identifier">NW</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem for trying to create a blank name</span> <span class="cwebmacronumber">6.3.1</span>&gt;<span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">evaluation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">)))</span>
<span class="identifier">evaluation</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">, </span><span class="identifier">evaluation</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">evaluation</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem for trying to create an existing kind as a new instance</span> <span class="cwebmacronumber">6.3.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">evaluation</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">evaluation</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem for trying to create any existing meaning as a new instance</span> <span class="cwebmacronumber">6.3.3</span>&gt;<span class="plain">;</span>
<span class="functiontext">Assertions::Creator::tabular_definitions</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">);</span>
<span class="identifier">NounPhrases::annotate_by_articles</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">);</span>
<span class="identifier">Problems::Buffer::redirect_problem_sentence</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="identifier">name_entry</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">);</span>
<span class="functiontext">Assertions::Copular::make_assertion</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">);</span>
<span class="identifier">Problems::Buffer::redirect_problem_sentence</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">, </span><span class="identifier">NW</span><span class="plain">);</span>
<span class="identifier">evaluation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">&gt;(</span><span class="identifier">NW</span><span class="plain">))</span>
<span class="identifier">evaluation</span><span class="plain"> = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">)))</span>
<span class="identifier">evaluation</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">, </span><span class="identifier">evaluation</span><span class="plain">);</span>
<span class="functiontext">Assertions::Creator::tabular_definitions</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem to say that the creation failed</span> <span class="cwebmacronumber">6.3.4</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">objections</span><span class="plain"> &gt; 0) </span><span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_3_1"></a><b>&#167;6.3.1. </b>Usually if the source text makes this mistake in one row, it makes it in
lots of rows, so we issue the problem just once.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for trying to create a blank name</span> <span class="cwebmacronumber">6.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blank_objections</span><span class="plain"> == 0) {</span>
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &amp;</span><span class="identifier">row_count</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableWithBlankNames</span><span class="plain">),</span>
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">name_entry</span><span class="plain">,</span>
<span class="string">"%1 is being used to create values, so that the first column needs "</span>
<span class="string">"to contain names for these new things. It's not allowed to contain "</span>
<span class="string">"blanks, but row %4 does (see %3)."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">objections</span><span class="plain">++; </span><span class="identifier">blank_objections</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_3">&#167;6.3</a>.</p>
<p class="inwebparagraph"><a id="SP6_3_2"></a><b>&#167;6.3.2. </b>This is a special case of the next problem, but enables a clearer problem
message to be issued. (It's not as unlikely a mistake as it looks, since
kind names can legally be written into other columns to indicate the kinds
of the contents.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for trying to create an existing kind as a new instance</span> <span class="cwebmacronumber">6.3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &amp;</span><span class="identifier">row_count</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableEntryGeneric</span><span class="plain">),</span>
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">name_entry</span><span class="plain">,</span>
<span class="string">"In row %4 of %1, the entry %3 is the name of a kind of value, "</span>
<span class="string">"so it can't be the name of a new object."</span><span class="plain">);</span>
<span class="identifier">objections</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_3">&#167;6.3</a>.</p>
<p class="inwebparagraph"><a id="SP6_3_3"></a><b>&#167;6.3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for trying to create any existing meaning as a new instance</span> <span class="cwebmacronumber">6.3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Existing meaning was: $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">evaluation</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(2, </span><span class="identifier">name_entry</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind_of</span><span class="plain">(3, </span><span class="identifier">evaluation</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::quote_number</span><span class="plain">(5, &amp;</span><span class="identifier">row_count</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableCreatedClash</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, and row %5 of the first column of that table is %2, which "</span>
<span class="string">"I ought to create as a new value of %4. But I can't do that: it already "</span>
<span class="string">"has a meaning (as %3)."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">objections</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_3">&#167;6.3</a>.</p>
<p class="inwebparagraph"><a id="SP6_3_4"></a><b>&#167;6.3.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem to say that the creation failed</span> <span class="cwebmacronumber">6.3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Eval is $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">evaluation</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(4, </span><span class="identifier">name_entry</span><span class="plain">);</span>
<span class="identifier">Problems::quote_number</span><span class="plain">(5, &amp;</span><span class="identifier">row_count</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableDefiningNothing</span><span class="plain">),</span>
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">name_entry</span><span class="plain">,</span>
<span class="string">"In row %5 of %1, the entry %4 seems not to have defined "</span>
<span class="string">"a thing there, so perhaps the first column did not consist "</span>
<span class="string">"of new names?"</span><span class="plain">);</span>
<span class="identifier">objections</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_3">&#167;6.3</a>.</p>
<p class="inwebparagraph"><a id="SP6_4"></a><b>&#167;6.4. Property assignment. </b>Suppose column 3, say, is called "alarm call" and contains times. Clearly
this is a property, and we have to give those property values to whatever
has been created in their corresponding column 1s. That means those
individual values need permission to have the "alarm call" property. But
what about other values of the same kind which aren't mentioned in the
table: do they get permission as well? We're going to say that they do.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Assign properties for these values as enumerated in subsequent columns</span> <span class="cwebmacronumber">6.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;no_columns</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Ensure that a property with the same name as the column name exists</span> <span class="cwebmacronumber">6.4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == 1)</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span>
<span class="functiontext">Calculus::Propositions::Abstract::to_provide_property</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">),</span>
<span class="functiontext">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;kind_defined_in_this_table</span><span class="plain">),</span>
<span class="identifier">prevailing_mood</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;contains_property_values_at_run_time</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Passively allow the column to become the property values</span> <span class="cwebmacronumber">6.4.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Actively assert the column entries as property values</span> <span class="cwebmacronumber">6.4.3</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_4_1"></a><b>&#167;6.4.1. </b>It's probably, but not certainly, the case that the column name is new, and
not yet known to be a property. If so, this is where it becomes one. By
traverse 2, if not before, we will be able to give it a kind, since after
table-stocking the column will have a kind for its entries.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Ensure that a property with the same name as the column name exists</span> <span class="cwebmacronumber">6.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">&lt;</span><span class="identifier">unfortunate</span><span class="plain">-</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">column</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">&gt;(</span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">));</span>
<span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Properties::Valued::obtain</span><span class="plain">(</span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::Valued::kind</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="identifier">kind</span><span class="plain"> *</span><span class="identifier">CK</span><span class="plain"> = </span><span class="functiontext">Tables::Columns::get_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">CK</span><span class="plain">) == </span><span class="identifier">CON_rule</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">CK</span><span class="plain">) == </span><span class="identifier">CON_rulebook</span><span class="plain">)) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K1</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">K2</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">CK</span><span class="plain">, &amp;</span><span class="identifier">K1</span><span class="plain">, &amp;</span><span class="identifier">K2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">))) {</span>
<span class="identifier">CK</span><span class="plain"> = </span><span class="identifier">Kinds::binary_construction</span><span class="plain">(</span>
<span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">CK</span><span class="plain">), </span><span class="identifier">K_action_name</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">);</span>
<span class="functiontext">Tables::Columns::set_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">CK</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">CK</span><span class="plain">) </span><span class="functiontext">Properties::Valued::set_kind</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">CK</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_4">&#167;6.4</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>When a table column is used to create a property of an object, its name
becomes the name of a new property. To avoid confusion, though, there are
some misleading names we don't want to allow for these properties.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">unfortunate</span><span class="plain">-</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">column</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">&gt; ::=</span>
<span class="identifier">location</span><span class="plain"> ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_TableColumnLocation problem</span> <span class="cwebmacronumber">7.1</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_TableColumnLocation problem</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">NEW_TC_PROBLEM</span><span class="plain">;</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableColumnLocation</span><span class="plain">),</span>
<span class="identifier">table_being_examined</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">table_cell_node</span><span class="plain">,</span>
<span class="string">"In %1, the column name %3 cannot be used, because there would be too "</span>
<span class="string">"much ambiguity arising from its ordinary meaning referring to the "</span>
<span class="string">"physical position of something."</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="SP6_4_2"></a><b>&#167;6.4.2. </b>Now for something sneaky. There are two ways we can actually assign the
property values: active, and passive. The passive way is the sneaky one, and
it relies on the observation that if we're going to store the property values
in this same table at run-time then we don't need to do anything at all: the
values are already in their correct places. All we need to do is notify the
property storage mechanisms that we intend this to happen.
</p>
<p class="inwebparagraph">(Take care editing this: the call works in quite an ugly way and relies on
following immediately after a permission grant.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Passively allow the column to become the property values</span> <span class="cwebmacronumber">6.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == 1)</span>
<span class="functiontext">Properties::OfValues::pp_set_table_storage</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.tcu_iname</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_4">&#167;6.4</a>.</p>
<p class="inwebparagraph"><a id="SP6_4_3"></a><b>&#167;6.4.3. </b>Active assertions of properties are, once again, a matter of calling the
assertion handler, simulating sentences like "The P of X is Y".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Actively assert the column entries as property values</span> <span class="cwebmacronumber">6.4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">name_entry</span><span class="plain">, *</span><span class="identifier">data_entry</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">name_entry</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">,</span>
<span class="identifier">data_entry</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">&gt;columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="identifier">name_entry</span><span class="plain"> &amp;&amp; </span><span class="identifier">data_entry</span><span class="plain">;</span>
<span class="identifier">name_entry</span><span class="plain"> = </span><span class="identifier">name_entry</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">,</span>
<span class="identifier">data_entry</span><span class="plain"> = </span><span class="identifier">data_entry</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="identifier">Problems::Buffer::redirect_problem_sentence</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="identifier">name_entry</span><span class="plain">, </span><span class="identifier">data_entry</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Make an assertion that this name has that property</span> <span class="cwebmacronumber">6.4.3.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">Problems::Buffer::redirect_problem_sentence</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_4">&#167;6.4</a>.</p>
<p class="inwebparagraph"><a id="SP6_4_3_1"></a><b>&#167;6.4.3.1. </b>Note that a blank means "don't assert this property", it doesn't mean
"assert a default value for this property". The difference is very small,
but the latter might cause contradiction problem messages if there are
also ordinary sentences about the property value, and the former won't.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Make an assertion that this name has that property</span> <span class="cwebmacronumber">6.4.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">name_entry</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == 2) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">data_entry</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(&lt;</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">-</span><span class="identifier">blank</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">data_entry</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">data_entry</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">val</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"misevaluated cell"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">data_entry</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">);</span>
<span class="functiontext">Assertions::PropertyKnowledge::assert_property_value_from_property_subtree_infs</span><span class="plain">(</span>
<span class="identifier">P</span><span class="plain">, </span><span class="identifier">subj</span><span class="plain">, </span><span class="identifier">data_entry</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_4_3">&#167;6.4.3</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="reserved">table</span><span class="plain"> *</span><span class="functiontext">Tables::Defining::defined_by_table</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;construct</span><span class="plain">-&gt;</span><span class="identifier">named_values_created_with_table</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::Defining::set_defined_by_table</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">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no such kind"</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;construct</span><span class="plain">-&gt;</span><span class="identifier">named_values_created_with_table</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::Defining::defined_by_table is used in 9/tc (<a href="9-tc.html#SP5_4_2">&#167;5.4.2</a>, <a href="9-tc.html#SP5_4_2_7">&#167;5.4.2.7</a>).</p>
<p class="endnote">The function Tables::Defining::set_defined_by_table is used in <a href="#SP6">&#167;6</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="19-rsft.html">Back to 'Runtime Support for Tables'</a></li><li><a href="19-lr.html">Continue with 'Listed-In Relations'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>