Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0002129Core InformUnderstandingpublic2020-05-29 14:142020-05-29 15:47
Reporterotistdog 
Assigned To 
PrioritynormalSeveritymildReproducibilityalways
StatusnewResolutionopen 
Platformx86OSLinuxOS VersionAny
Product Version6M62 
Target VersionFixed in Version 
Summary0002129: Ordering of generated I6 statements in parse_name routines artificially limits "Understand" statements?
Description[Note that I am quite possibly misunderstanding some or all of what I'm seeing here, so please forgive any errors.]

The example creates tribbles that are defined with two properties, a new kind of value (color) and a number (spot count).

WWI documents how to use the color property as something that the parser can understand as relevant to the tribbles. The example uses this method for the color property, which makes the first test me command ("x red tribble") work as expected.

It also seems as though it should be possible to refer to the tribbles via their spot count property, with an appropriate understand phrase. The statement:

  Understand "with [number] spots" as a tribble when the spot count of the item described is the number understood.

seems like it is appropriate constructed, but it does not function. No other "test me" command works as expected.

In tracing the generated I6 code, the routine generated for use as the parse_name property for the tribble kind (Parse_Name_GV93 in the particular output I'm looking at) includes a section:

            if ((parser_action ~= ##TheSame) && (pass == 1)) {
                while (WordInProperty(NextWordStopped(), self, name)) f = true;
                wn--; try_from_wn = wn;
            }
                if (Cond_Token_161() == GPR_FAIL) jump Fail_1;
                if (NextWordStopped() ~= 'with') jump Fail_1;
                w = ParseTokenStopped(GPR_TT, DECIMAL_TOKEN);
                if (w ~= GPR_NUMBER) jump Fail_1; rv = GPR_NUMBER;
                if (NextWordStopped() ~= 'spots') jump Fail_1;
                try_from_wn = wn; f = true; continue;
                .Fail_1; wn = try_from_wn;

This passage makes use of the Cond_Token_161() function apparently created by the "with N spots" understand statement:

[ Cond_Token_161 ;
    if ((((GProperty(OBJECT_TY, self,p15_spot_count) == parsed_number)))) return GPR_PREPOSITION;
    return GPR_FAIL;
];

Note that the structure of Cond_Token_164() looks correct and seems like it should function. The issue seems to be that it checks the value of parsed_number, which is not set at the time that the function is called in the parse_name routine.

If the order of the parse_name passage is manually changed so that Cond_Token_164() is called *after* the "with N spots" phrase is checked, like so:

            if ((parser_action ~= ##TheSame) && (pass == 1)) {
                while (WordInProperty(NextWordStopped(), self, name)) f = true;
                wn--; try_from_wn = wn;
            }
                if (NextWordStopped() ~= 'with') jump Fail_1;
                w = ParseTokenStopped(GPR_TT, DECIMAL_TOKEN);
                if (w ~= GPR_NUMBER) jump Fail_1; rv = GPR_NUMBER;
                if (NextWordStopped() ~= 'spots') jump Fail_1;
                if (Cond_Token_161() == GPR_FAIL) jump Fail_1;
                try_from_wn = wn; f = true; continue;
                .Fail_1; wn = try_from_wn;

then the call to ParseTokenStopped() will set parsed_number appropriately, and Cond_Token_164() will function as desired. If the modified source code is run through the Inform6 compiler, it compiles successfully, and all test me commands work as expected (even the one referring to the non-existent two-spotted tribble).
Minimal Source Text To Reproduce
"Spot the Difference"

Color is a kind of value. The colors are red, blue and green.

A tribble is a kind of thing. A tribble has a number called spot count. The verb to sport spots means 
the spot count property. A tribble has a color. Understand the color property as describing a tribble. 
The description of a tribble is usually "It is [color] and has [spot count] spot[s]."

For printing the name of a tribble:
	say "[color] tribble".

For printing the plural name of a tribble:
	say "[color] tribbles".

[Definition: a number (called X) is self-spot-matching if the item described is a tribble and X is the 
spot count of the item described.
Understand "with [self-spot-matching number] spots" as a tribble. [thanks, zarf!]]

Understand "with [number] spots" as a tribble when the spot count of the item described is 
the number understood.

Cargo Hold is a room.

There is a red tribble in Cargo Hold. It sports spots 3.

There is a blue tribble in Cargo Hold. The spot count of it is 4.

test me with "x red tribble / x tribble with 3 spots / get tribble with 4 spots / x tribble with 
2 spots"
Additional InformationNote that this may be a general issue affecting many uses of "<value> understood" in understand statements, i.e. "the <whatever> understood" cannot be reliably used in a conditional understanding because the relevant token will be parsed and the related internal "<value> understood" variable (always parsed_number?) will be set only *after* the associated Cond_Token_N() routine is called, not before. If so, a generic fix to the change in the order of test routine calls in the generated parse_name routines would substantially increase the power of understand statements. For example:

     Understand "[color]" as a tribble when the color of the item described is the color understood and the player is not color-blind.

which I don't think can be made to function without changing the test routine order as in the bug description above.

It doesn't naively look as though changing the parse_name test evaluation order would cause any serious side effects, as a parse_name failure would be expected to rewind the next word pointer appropriate regardless of the particular reason for the failure.

Note that issue 0002042 seems to have a similar root cause, though a different use case.

Also note that the commented out part of the example code shows a workaround produced by zarf on a forum discussion thread about this https://intfiction.org/t/understanding-things-via-their-number-based-properties/10158 [^]). This makes the functionality possible at the expense of creating special-purpose adjectives.
TagsNo tags attached.
Effect(serious/mild) Game compiles but misbehaves
Attached Files

- Relationships

-  Notes
(0004913)
otistdog (reporter)
2020-05-29 14:48

My color-blindness example in "Additional Information" is a poor choice -- it will already work with something like:

   A person can be color-blind. Understand the color property as describing a tribble when the player is not color-blind.

I'm having trouble coming up with a case that couldn't be addressed using other functionality found in I7 right now. Still, the compiler accepts the "with N spots" construction, and it creates a perfectly serviceable routine from it -- even if the use of said routine neuters its functionality in 6M62. I would hate to see any solution to this issue that forbids the understand statement from compiling, especially if a small change in the parse_name routine's test ordering will make it work without any unexpected harm.
(0004914)
otistdog (reporter)
2020-05-29 15:47

As an alternate example of a use case that would be enabled by this change:

======== start code ========

"Sorting Rocks"

Color is a kind of value. The colors are uncolored, white, gray, black, brown, red, orange, yellow, green, blue and purple.

Mineral type is a kind of value. The mineral types are sedimentary, metamorphic and igneous.

A mineral is a kind of value. The minerals are defined by the Table of Mineral Data.

Table of Mineral Data
mineral mineral type color
basalt igneous black
granite metamorphic white
obsidian igneous black
pumice igneous gray
quartz metamorphic uncolored
sandstone sedimentary yellow
slate sedimentary gray

A rock is a kind of thing. A rock has a mineral. Understand the mineral property as describing a rock. Understand "sample" as a rock.

Understand "[mineral type]" as a rock when the mineral type of the mineral of the item described is the mineral type understood.

Rule for printing the name of a rock:
say "[mineral] sample".

Rule for printing the plural name of a rock:
say "[mineral] samples".

Canyon is a room.

There is a basalt rock in Canyon.

There is a sandstone rock in Canyon.

test me with "x sedimentary / x sandstone / take igneous / take metamorphic".

========= end code =========

In this case, it's necessary to access a property of a property and compare this to user input in order to parse the meaning. I don't think any legal code along the lines of:

     Understand the mineral type property of the mineral property as describing a rock.

is possible in 6M62. It may be possible to set up a relation between minerals and mineral types (called "mineral classification", for example) and have a statement along the lines of:

     Understand "[something related by mineral classification]" as a rock.

to get the desired effect, but this is an indirect approach and requires definition of a special-purpose relation.

Likewise, it would be possible to add mineral type and color properties to rocks and use a "when play begins" rule to auto-set these properties for all rocks on start, but that is again indirect.

- Issue History
Date Modified Username Field Change
2020-05-29 14:14 otistdog New Issue
2020-05-29 14:48 otistdog Note Added: 0004913
2020-05-29 15:47 otistdog Note Added: 0004914


Copyright © 2000 - 2010 MantisBT Group
Powered by Mantis Bugtracker