Understanding Left from Right

I have an issue where when a pronoun is invoked, it seems that understanding the difference between left and right can be messed up. The code is under the rant. The offending output is this:

kitchen
You can see Sally, Bob and a Bucket-shaped android here.

>look her arm
What do you want to look: 1) Sally's left arm or 2) Sally's right arm?

>left
You see nothing special about Sally's right arm.

>

I am plain stumped on this one.

Edit: this may be a further clue…

>look her arm
What do you want to look: 1) Sally's left arm or 2) Sally's right arm?

>1
You can't see any such thing.

>

How can it not be in scope, but still end up in the asking which do you mean list? Also, it is there with Trace 6 on… and up until the very end, the parser is saying “Sally’s left arm…?” and then right at the very end decides on the right arm or nothing!

[rant]I tried to provide a stripped down version of my application for the question… but believe me, this IS the stripped down version. I removed thousands of other lines to have this “core functionality” version to share. This doesn’t include all the custom actions and reporting, assembly libraries, etc.

The parts that are probably relevant are down in Chapter 1 - Filtering Command by Pronoun and Book 3 - Arms segments, but I have no idea why it’s doing this.

[code]
Volume 1 - Settings

Use MAX_OBJECTS of 10000.
Use maximum things understood at once of at least 500.
Use MAX_PROP_TABLE_SIZE of 10000000.
Use MAX_STATIC_DATA of 10000000.
Use MAX_SYMBOLS of 1000000.
Use SYMBOLS_CHUNK_SIZE of 100000.
Use ALLOC_CHUNK_SIZE of 64000.
Use MAX_ARRAYS of 1000000.
Use MAX_NUM_STATIC_STRINGS of 1000000.
Use MAX_EXPRESSION_NODES of 1024.
Use MAX_CLASSES of 3000.
Use MAX_VERBS of 1000.
Use DICT_WORD_SIZE of 30.
Use dynamic memory allocation of at least 16384.
Use maximum text length of at least 3000.
Use american dialect.

To consider (x - a nothing based rule):
follow x;

To decide which object is the cleaned holder of (x - a thing):
if the holder of x is nothing:
decide on x;
otherwise:
decide on the holder of x;

When play begins:
repeat with x running through things:
if the holder of x is not a room and the holder of x is not an enterable container:
now x is unscopable;
if x is incorporated by something (called y):
now the original incorporater of x is y;
repeat with z running through directions:
now z is unscopable;

Include (-
Replace PrintInferredCommand;

[ PrintInferredCommand; ];
-) before “Parser.i6t”.

Volume 2 - Managing Scope

Book 1 - Scopability by Brady Garvin

Include Scopability by Brady Garvin.

Book 2 - Scoping Directions

A direction can be scopable or unscopable.

Understand “n/north/s/south/e/east/w/west/nw/northwest/ne/northeast/sw/southwest/se/southeast/u/up/d/down/in/inside/out/outside” as “[direction]”.

After reading a command (this is the put directions back in scope if actually being used rule):
if the player’s command includes “go” or the player’s command includes “[direction]”:
repeat with x running through directions:
now x is scopable;

Book 3 - The Relevant List

A thing can be reset unscopable. A thing can be special scope.

Definition: a thing is reset unscopable if the holder of it is not the holder of the player and it is not special scope.

Asking which is initially false;

Before asking which do you mean (this is the determine if asking which do you mean sequence rule):
now asking which is true;

Definition: a thing is relevant if it is in the location or the cleaned holder of it is in the location or it is special scope.

Relevant list is a list of objects that varies.

Before reading a command (this is the populate relevant list rule):
truncate relevant list to 0 entries;
repeat with y running through relevant things:
add y to relevant list, if absent;

Last every turn (this is the reset unscopability rule):
repeat with x running through relevant list:
if x is reset unscopable:
now x is unscopable;
repeat with y running through directions:
now y is unscopable;
now asking which is false;

Volume 3 - Disambiguation

Book 1 - Disambiguation Control by Jon Ingold

Include Disambiguation Control by Jon Ingold.

Use disambiguation list length of at least 100.

Chapter 1 - No Initial Expectations (in place of Chapter - Initial Expectations in Disambiguation Control by Jon Ingold

[Default assumptions are not the reason we want this extension. “The match list” being exposed to I7 is the most important thing thus far.]

Book 2 - Numbered Disambiguation Choices by Aaron Reed

Include Numbered Disambiguation Choices by Aaron Reed.

The Numbered Disambiguation Choices don’t use number rule is not listed in any rulebook.

The Numbered Disambiguation Choices preface disambiguation objects with numbers rule is not listed in any rulebook.

A thing can be numbered_disambiguation_proper_cleaned.

Before asking which do you mean:
repeat with x running through the match list:
if x is not proper-named:
now x is numbered_disambiguation_proper_cleaned;
now x is proper-named;

After asking which do you mean:
now every thing that is numbered_disambiguation_proper_cleaned is not proper-named;
now every thing that is numbered_disambiguation_proper_cleaned is not numbered_disambiguation_proper_cleaned;

First before printing the name of something (called macguffin) while asking which do you mean (this is the New Numbered Disambiguation Choices preface disambiguation objects with numbers rule):
if macguffin is not listed in match list:
do nothing;
otherwise:
if disambiguation-busy is false:
now disambiguation-busy is true;
repeat with x running through match list:
if x is macguffin:
add macguffin to the list of disambiguables, if absent;
now the disambiguation id of macguffin is the number of entries in list of disambiguables;
say “[before disambiguation number text][the number of entries in list of disambiguables][after disambiguation number text]”;

Book 3 - Disambiguating Homographic Prop_Objects

[Sometimes prop_objects will end up being grouped together because the player doesn’t know any better due to the conditionals attached to understand phrases. However, beneath the surface of what the player knows, the objects are actually not identical. This section makes sure the player always has the ability to select one of the grouped items instead of having the parser simply pick the first one.]

A thing has a text called group_id.

Understand the group_id property as describing a thing.

When play begins:
Let N be 1;
repeat with x running through things:
now the group_id of x is “group_id_[N]”;
increment N;

Book 4 - Abandoning After Asking Which Do You Mean

This is the extended disambiguation printing rule:
if the message-id-requested is:
– 1: say "Please be more specific - " (A);
– 2: say "Whom [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]: " (B);
– 3: say "What [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]: " ©;
– 4: say “Whom [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]?[paragraph break]” (D);
– 5: say “What [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]?[paragraph break]” (E);
– 6: say "whom [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]: " (F);
– 7: say "what [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]: " (G);
– 8: say “whom [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]?[paragraph break]” (H);
– 9: say “what [regarding the player][do] [we] want[actor-or-player] to [print-or-construct]?[paragraph break]” (I);
– 10: say “?[line break]” (J);
– 11: say “?[paragraph break]” (K);
– 12: say “[We] [can] only have one item here. Which exactly?” (L);
– 20: say “take things from” (M);
– 21: say “put things in” (N);
– 22: say “put things on” (O);

The extended disambiguation printing rule substitutes for the disambiguation printing rule.

Book 5 - Abandoning While Asking Which Do You Mean

Rule for asking which do you mean while the player’s command includes “no”:
say “Decisions, decisions… none of these will do for now.”;
follow the put temporarily descoped for pronouns things back in scope rule;

Volume 4 - Possession and Ownership

Book 1 - Parsing Possessives

First after reading a command (this is the after manage possessives in the players command rule):
if the player’s command includes “your”:
replace the matched text with “theirs”;
if the player’s command includes “my”:
replace the matched text with “your”;
let N be text;
let N be the player’s command;
replace the regular expression “(\w)[’]s” in N with “\1 [’]s”;
replace the regular expression “s” in N with “s [’]s\1”;
change the text of the player’s command to N;

Understand “your” as a thing when the player is the holder of the item described. Understand “theirs” as a thing when the person asked is the holder of the item described.

Volume 5 - Categories vs Kinds

Book 1 - Categories, Subcategories, and Specific Types

A category is a kind of value. Generic category is a category. A thing has a category.
A subcategory is a kind of value. Generic subcategory is a subcategory. A thing has a subcategory.
A specific type is a kind of value. Generic type is a specific type. A thing has a specific type.

Volume 6 - Gender and Age

Book 1 - Age

A perceived age is a kind of value. Perceived age are perceived infant, perceived child, perceived young, perceived adult, perceive old. A person has a perceived age. A person is usually perceived adult.

Book 2 - Gender

Chapter 1 - Filtering Commands by Pronoun

A thing can be temporarily descoped for pronouns.

This is the put temporarily descoped for pronouns things back in scope rule:
now everything that is temporarily descoped for pronouns is scopable;

Last after reading a command while the player’s command includes “her”:
repeat with x running through relevant things that are held by a person:
if the holder of x is not female:
now x is temporarily descoped for pronouns;
now x is not scopable;

Understand “her” as a thing when the item described is female.
Understand “her [thing]” as a thing when a female person holds the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.
Understand “her [thing]” as a thing when a female person wears the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.

Last after reading a command while the player’s command includes “his”:
repeat with x running through relevant things that are held by a person:
if the holder of x is not male or the holder of x is neuter:
now x is temporarily descoped for pronouns;
now x is not scopable;

Understand “him” as a thing when the item described is male and the item described is not neuter.
Understand “his [things]” as a thing when a male person holds the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.
Understand “his [things]” as a thing when a male person wears the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.

Last after reading a command while the player’s command includes “its”:
repeat with x running through relevant things that are held by a person:
if the holder of x is not neuter:
now x is temporarily descoped for pronouns;
now x is not scopable;

Understand “it” as a thing when the item described is neuter.
Understand “its [things]” as a thing when a male person holds the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.
Understand “hits [things]” as a thing when a male person wears the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.

Volume 7 - Body Parts

Book 1 - Body Parts Main

A body part is a kind of thing. body part category is a category. A body part is usually body part category.

A thing has a thing called original incorporater.

Before printing the name of a body part (called x):
if the original incorporater of x is not proper-named:
now the original incorporater of x is proper-named;
say "[regarding the original incorporater of x][possessive] ";
now the original incorporater of x is not proper-named;
otherwise:
say "[regarding the original incorporater of x][possessive] ";

Book 3 - Arms

Arm subcategory is a subcategory.

Some arms are a kind of body part. Some arms are usually arm subcategory.

Understand “arm/arms” as “[arm]”. Understand “[arm]” as a thing when the item described is arm subcategory.
Understand “[something related by reversed incorporation] 's [arm]” as a thing when the item described is arm subcategory.

After reading a command while the player’s command includes “[arm]” (this is the scope arms rule):
repeat with x running through relevant list:
if x is arm subcategory:
now x is scopable;

Left arm type is a specific type.

A left arm is a kind of arms. A left arm is usually left arm type. 1 left arm is usually a part of every person. Understand “left” as a thing when the item described is left arm type.

Rule for printing the name of a left arm:
say “left arm”;

Rule for printing the plural name of a left arm:
say “left arms”;

Right arm type is a specific type.

A right arm is a kind of arms. A right arm is usually right arm type. 1 right arm is usually a part of every person. Understand “right” as a a thing when the item described is right arm type.

Rule for printing the name of a right arm:
say “right arm”;

Rule for printing the plural name of a right arm:
say “right arms”;

Volume 10 - The Test Game

The kitchen is a room.

The player is in the kitchen.

Sally is a female person in the kitchen.

Bob is a male person in the kitchen.

Bucket-shaped android is a neuter person in the kitchen. Bucket-shaped android is not proper-named.
[/code][/rant]

Thanks for posting the test case! Not to be needy, but could you link the versions of the extensions you have – I don’t have Scopability in particular, though I guess I can get Numbered Disambiguation Choices from the Public Library.

I’m following your project with interest – the reason I didn’t say anything about your scope caching problem was partly because I didn’t have the extensions to try your test case out, and also I really don’t understand I6 parser optimization and like that.

[rant]Yeah, the extensions are another thing. They are great and if they hadn’t been written, I’d never even be able to attempt this myself, but it does make for this being less portable. I always worry that people think I’m greedy and entitled… but really, I’m actually quite grateful people have shared all the hardcore code in the I7 core and in various extensions in the first place, but terrified that I’ll not be able to finish my project after literally hundreds of hours of work, so I’m posting on this forum in desperation, not out of entitlement.

I understand that Inform wasn’t originally intended to do what I’m trying to do with it. Having thousands of objects and a more “intuitively realistic” model for the world wasn’t what the founders had in mind. At one point I thought it was actually going to be impossible to finish at all because Inform kept crashing with how much stuff I was putting in it, and I was pretty upset… again, not because I feel entitled to it, it’s free and the fact that it exists at all is pretty cool, but I was upset that I ran into that problem after sinking hundreds of hours into the project. Luckily, after finding some of these other extensions and gaining some new knowledge about the compiler, I was able to continue and have up to about 5000 things before performance really starts to go downhill, which is plenty.

If I ever finish this framework and share it, I’d be afraid of breakage or loss of the system because it is in so many pieces, and wonder if it ever gets to working and doing everything I want if I can ask other authors if I can package their work into the release… because it’s all integral to the overall system working.[/rant]

Disambiguation Control by Jon Ingold is here:
https://github.com/i7/extensions/blob/master/Jon%20Ingold/Disambiguation%20Control.i7x

Scopability by Brady Garvin is here:
https://github.com/i7/extensions/blob/master/Brady%20Garvin/Scopability.i7x

Numbered Disambiguation Choices by Aaron Reed is here:
http://inform7.com/extensions/Aaron%20Reed/Numbered%20Disambiguation%20Choices/index.html

Updated findings:

I stripped out Disambiguation Control by Jon Ingold and Numbered Disambiguation Choices by Aaron Reed as a test, just as part of the procedure to isolate the cause. They do not appear to be the cause.

I tried some more use cases and came up with this:

You can see a woman, Bob and a being here.

>look her left arm
You see nothing special about the woman's left arm.

>look woman's left arm
You see nothing special about the woman's left arm.

>look his left arm
What do you want to look: 1) your left arm or 2) Bob's left arm?

>2
You see nothing special about Bob's right arm.

>look bob's left arm
You see nothing special about Bob's left arm.

>look its left arm
You see nothing special about the being's left arm.

>look its arm
What do you want to look: 1) being's left arm or 2) being's right arm?

>left
You see nothing special about the being's right arm.

>look its arm
What do you want to look: 1) being's left arm or 2) being's right arm?

>1
I only understood you as far as wanting to look the being's right arm.

>

Essentially, pronouns are fine… UNLESS asking which do you mean runs. Combining pronoun use with asking which do you mean results in the last item added to the code to be selected. If I reverse the order in which left arms and right arms are referenced in the code, now it always picks the left arm in such cases instead.

I still don’t know the root cause, but if anyone else is looking, perhaps this insight is useful.

Ok… I think I may have found the problem, but I don’t understand (hyuck hyuck) why it’s a problem.

Understand "her [things]" as a thing when a female person holds the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.

Changed to:

Understand "her" as a thing when a female person holds the item described and the cleaned holder of the item described is not the player and the cleaned holder of the item described is not the person asked.

Would someone be willing to explain the difference, and why the first (which looks more intuitively correct) is wrong?

I’m surprised the first works at all. Here’s my attempt at explaining what the parser is thinking.

[rant=Explanation]Let’s say Inform is running through this command:

EXAMINE HER ARM

It looks at the first word, which could be the start of the grammar line “examine [something]”. So now it moves to the next word and sees if it can be parsed as [something].

HER ARM

The first word could be the pronoun “her”, so it tries that interpretation.

ARM

But now this word is left over, so that wasn’t right. Set the potential parser error to be “I only understood you as far as wanting to examine her.” and go back a step.

HER ARM

The first word could also match the Understand line “her [things]”. In that case, we need the name of one or more things next.

ARM

This could be the name of a thing, but there are two matches in scope. Ask the player which one they want. (Assume they said the left.)
Now we’ve got this structure.

Examine [HER woman’s left arm]

The block on the right can refer to any thing held by a woman, so it looks for things held by women which are in scope. It finds two: the left arm and the right arm. Since the Understand line didn’t say which thing it should refer to (and it’s already asked the player to clarify something for this input), it defaults to whichever was defined higher in the code.

Usually Inform won’t let you get away with that, because of things like “x her her her her her her her her her her her her her her her her myself”.

With the second line, however, once Inform gets to HER ARM:

HER ARM

We know now that “her” is not a pronoun (that interpretation causes a parser error), so let’s try the Understand line. We can have any number of words referring to the same object in a row, so let’s see if “her” and “arm” can mean the same thing. They can refer to two things in scope: her left arm, and her right arm. Ask the player which they mean, and we have no more words, so parsing is complete.[/rant]

In general, you don’t want a [something] token in an Understand line for a noun. Just the word on its own will suffice.

Thank you for the detailed explanation! I don’t know how the parser code works from a technical perspective, but I do know better what to watch out for now from a process perspective!

I don’t quite follow this; won’t Inform ask for two disambiguations in a row if necessary? Like this (from the source code you’d expect):

By the way, I got an error in Scopability the first time I tried to compile it; it had a semicolon between two assertions when it should have had a period. (“An object can be scopable or unscopable; an object is usually scopable.”) Someone who can github might want to report that.