Disambiguation Control by Jon Ingold and L602

This extension seems to be broken in L602. I don’t know if Jon will read this, or if this is a known issue, but I don’t know where else to ask. Beyond that, is there a L602 compatible extension to do the same kind of thing… give greater control over the default suggestions?

Edit: It looks like this is a known issue, but perhaps no one is working on it as it is a complex rewrite of part of the old compiler. I’ll start a new topic for how to solve the problems I am having sans this extension.

I don’t know how high updating this is on Jon’s to-do list – his day job is now running Inkle Studios, a choice-based IF company which you should totally check out if you haven’t done so!

Anyway, I went through the extension and bopped all the compiler errors. This was very much a Chinese Room Experiment kind of thing, as I don’t understand the I6 at all; I just went through the errors on the Console page and pasted in the corresponding code from the new parser. There were only a few changes necessary to get it to compile:

L__M(##Miscellany, 20); changed to best_etype = ANIMAAGAIN_PE;
L__M(##Miscellany, 21); changed to PARSER_COMMAND_INTERNAL_RM(‘D’); new_line; (in two places)
print (string) COMMA__TX; changed to print ", ";
print (string) OR__TX; changed to PARSER_CLARIF_INTERNAL_RM(‘H’);

and it looks like the new parser defines something in (or just after) NounDomain that the old one didn’t, so we need to include that in the replacement for NounDomain, so I added

[ PARSER_CLARIF_INTERNAL_R; ];

just before the Instead of “NounDomain” line.

I also changed one of the examples so it says “End the story finally” instead of “End the game.”

This is just a patch, or maybe a spackle, because as I said I don’t know what the underlying logic is; and it isn’t adaptive (the messages will read “What do you want to…” even if the story isn’t in second person present). But it does seem to compile and yield the desired result for the examples, and hopefully it’ll be something to get on with. I also hope Jon won’t mind me posting this!

Uploaded it as a .txt because my computer doesn’t seem to be able to find extensions when I go to upload them.
Disambiguation Control Fix.txt (111 KB)

This fix seems to work from my testing! Thank you!

Um, Matt - awesome! Thank you. If this is even vaguely works, and you felt like submitting it to the Public Library then please do.

cheers
jon

You’re welcome, and thanks for writing the extension! My last project would’ve been awful without it, as it had a lot of disambiguation tangles and I have never been able to get Does The Player Mean Rules to do anything I want.

I would have to go through and make some of the responses adaptive-friendly in order to submit it, and I don’t have time to do that for a while, but if no one else picks it up I’ll see what I can do.

I can do that if you want, I need a distraction from IntroComp work.

EDIT: Done, at least for the I7 part. I might have missed some text in the I6 sections.
github.com/i7/extensions/blob/m … ontrol.i7x

I’m having an issue with the multiple object list and this extension. I don’t know if it is related to L602 and this fixed version, or if it was there before, because prior to L602, I never used the multiple object list myself, and I don’t have multiple builds (I’m too scared and lazy for that…)

Anyway, when this extension is included it breaks the ability for the user to specify things in a multiple object action properly.

Include Disambiguation Control by Jon Ingold.

The kitchen is a room.

The player is in the kitchen.

An interloper is a kind of thing. 

An apple is a kind of thing.

An orange is a kind of thing.

3 interloper are in the kitchen.

There are 3 apple in the kitchen.

There are 3 orange in the kitchen.
kitchen
You can see three interlopers, three apples and three oranges here.

>take 2 apples and 1 orange
interloper: Taken.
interloper: Taken.
orange: Taken.

It always selects the first kind of item in the visible object list for the first kind of item in the multiple object list, instead of the actual kind that the user entered. I am way out of my depth on fixing this… I’d just be at it by blocking out bits of code one by one with comments and trying to narrow it down blind. Is anyone willing to take a look at this issue? My entire game premise kind of hinges on multiple object actions and the ability to strongly control disambiguation in ways only this extension provides. Otherwise, this extension is awesome and critical to me, but this is breaking my game badly.

Ohhhh snap, if you replace “nap” with “hit.” I checked and it’s already happening in 6G60. I also expect I’ll be way out of my depth but I’ll take a look.

ooh, crikey. I’m absolutely certain I never tested that kind of input, so it’s quite possible it doesn’t work properly. Off the top of my head, I don’t even know how Inform deals with that kind of specification. If you say “2 apples and 1 interloper and 3 oranges” does it get the rest right? If so, it should be fixable, since it’s clearly coping in general. But I’d be worried that the oranges picked up in your example are by chance, and it’s just choosing 3 items – that would be bad.

cheers
jon

I’m not sure, but I get a sinking feeling that this is the worse of the scenarios you outlined (of course I could be wrong):

You can see three interlopers, three apples and three oranges here.

>take 2 apples and 1 interloper
interloper: Taken.
interloper: Taken.

>take 1 orange and 1 apple
interloper: You already have that.
apple: Taken.

>

Here, it looks like it is just taking interlopers regardless of input, and always selecting the first in the list. It won’t even let you take more of a thing you have 1 of when multiply taking.

The syntax for doing three or more works without your extension:

>take 2 apples and 1 orange and 1 interloper
apple: Taken.
apple: Taken.
orange: Taken.
interloper: Taken.

Unfortunately, with your extension, the results are the same as when taking only two types of things… it is just taking the first two things it comes across and ignoring the rest of the command.

>take 2 apples and 1 orange and 1 interloper
interloper: Taken.
interloper: Taken.

I am sorry to just be over here somewhere in the world and ask over the internet for so much help, but I could never write all this from scratch. I really appreciate your extension (and a lot of other stuff that is shared in this community), but when things don’t work together like this use case I often can’t fix it myself. I need your disambiguation methods to deal with other issues, so if you have the time… :slight_smile: … it sounds like it might be tough though.

So in case this is any help, here’s the “trace 4” output from this (under 6G60):

[spoiler]kitchen
You can see three interlopers, three apples and three oranges here.

trace 4
[Parser tracing set to level 4.]

take two apples and two oranges
[ “take” take / “two” two / “apples” apples / “and” and / “two” two / “oranges” oranges ]
[Parsing for the verb ‘take’ (6 lines)]

[line 0 * ‘inventory’ -> Inv]
[line 0 token 1 word 2 : ‘inventory’]
[token resulted in failure with error type 1]

[line 1 * multi -> Take]
[line 1 token 1 word 2 : multi]
[Object list from word 2]
[Calling NounDomain on location and actor]
[NounDomain called at word 3
seeking indefinite object: plural
number wanted: 2
most likely GNAs of names: 4095
[ND made 3 matches]
[ND informed]

the apple…?

the apple…?

the apple…?
11 possible continuation nouns [Adjudicating match list of size 3 in context 2
indefinite type: plural
number wanted: 2
most likely GNAs of names: 4095
Scoring match list: indef mode 1 type 8, satisfying 0 requirements:

 You (46) in the kitchen :  deleted by ChooseObjects

 The interloper (47) in the kitchen : 4176 points

 The interloper (48) in the kitchen : 4176 points

 The interloper (47) rescored at: 3126 points

 The interloper (48) rescored at: 3126 points

Best guess the interloper (47)
Accepting it
Best guess the interloper (48)
Accepting it
Best guess ran out of choices
Made multiple object of size 2]
[ND appended to the multiple object list:
Entry 1: The interloper (47)
Entry 2: The interloper (48)
List now has size 2]
[Read connective ‘and’]
[Object list from word 5]
[Calling NounDomain on location and actor]
[NounDomain called at word 6
seeking indefinite object: plural
number wanted: 2
most likely GNAs of names: 4095
[ND made 3 matches]
[ND informed]

the orange…?

the orange…?

the orange…?
[Adjudicating match list of size 3 in context 2
indefinite type: plural
number wanted: 2
most likely GNAs of names: 4095
Scoring match list: indef mode 1 type 8, satisfying 0 requirements:

 The orange (53) in the kitchen : 4176 points

 The orange (54) in the kitchen : 4176 points

 The orange (55) in the kitchen : 4176 points

 The orange (53) rescored at: 3126 points

 The orange (54) rescored at: 3126 points

 The orange (55) rescored at: 3126 points

Best guess the orange (53)
Accepting it
Best guess the orange (54)
Accepting it
Best guess the orange (55)
Made multiple object of size 2]
[ND appended to the multiple object list:
Entry 3: The orange (53)
Entry 4: The orange (54)
List now has size 4]
[Merging 2 new objects to the 2 old ones]
[token resulted in success]
[line 1 token 2 word 7 : END]
Revising multiple object list of size 4 with 2nd nothing
Token 2 plural case: number with actor 0
Done: new size 4
[Line successfully parsed]

interloper: Taken.
interloper: Taken.
orange: Taken.
orange: Taken.

[/spoiler]

Which must be coming from this bit of the code:

[spoiler][code]
#ifdef DEBUG;
if (parser_trace>=4)
{
if (guessing)
{
print “[ND guessing]^”;
}
else
{ print “[ND informed]^”;

 for (i = 0: i< number_matched: i++)
if (match_list-->i~=0) print "^", (the) match_list-->i, "..?^";

}
}
#endif;[/code][/spoiler]

(Aside: I had a hard time finding this because I was searching for …? instead of …?)

So… it looks like whatever is going on there is successfully happening to the apple. Beyond that I don’t know.

Hmm. Looks to me like this bit

[code]if (line_ttype–>pcount == ELEMENTARY_TT or ATTR_FILTER_TT or ROUTINE_FILTER_TT)
{

		SafeSkipDescriptors();

		! save the current match state, since we're experimenting here
		@push token_filter; @push wn; @push match_length; @push match_from; @push number_matched;[/code]

…and I think what’s happening is that’s then doing a look ahead which builds a new match-list, which overwrites the original one. Maybe. That should never have worked on, say “PUT APPLES IN THE BIN” either in a room with both apples and oranges, but that’s my guess.

[I don’t have a copy of I7 installed right now.]

Anyway, I reckon if you make a new array (saved_match_list) just above the line of pushes, and fill it with the contents of the match_list array; and then on the row of pulls further down, copy the saved_match_list back into the match_list again … then I think it might work. Or actually, maybe you can just @push match_list; and then @pull it again? That might work. Try that first.

(Another way to test this line of thought; just comment out that entire block starting from the if line above… it’ll break a lot of stuff, but if this error goes away, then that’s a good sign.)

cheers
jon

Okay, addendum, I installed I7.

I think the following additions fix the issue:

[code] ! save the current match state, since we’re experimenting here
@push token_filter; @push wn; @push match_length; @push match_from; @push number_matched;

		[b]COBJ__SwapMatches();[/b][/code]

and

[code]COBJ__SwapMatches();

		! reset the position of the parser from before this pass
		@pull number_matched; @pull match_from; @pull match_length; @pull wn; @pull token_filter;[/code]

(So, the bold-typed lines are new. Turned out there was already a method in place for saving out a match-list while creating a new one).

This will need some testing, as I’m not 100% sure there aren’t occasions when it can reach this state having already swapped once elsewhere… but it definitely resolves the immediate problem, and if other bugs turn up, the calls in the code to COBJ__SwapMatches could always be replaced with something that saves to a named alternative array instead, easily enough.

Edit: file attached.

cheers
jon
disambiguation control.txt (111 KB)

Thank you very much for working on this! It looks to be working so far. I don’t have any specific use cases to test to try to break something somewhere else, so I’ll just plug away and if something else comes up I’ll post about it. Thanks again! I would be in serious trouble without this extension.