Proof of concept for Responsive Disambiguation (with a bug)

The following interaction bothers me:

If we get our game to ask a question with explicit answers, I think the game ought to be able to understand it. The parser determines whether the text typed at a disambiguation question is an attempt at answering the question by testing whether the first word is a verb (and treating it as a new command if it is), but while this generally works it will fall down when the object names contain verbs.

This is potentially a big problem for Threaded Conversation, when it might be nice to be able to respond to “What do you want to ask Bob about: what it might be worth or who would buy it?” with “buy.”

Anyway, I thought it might be nice to have disambiguation behavior that’s more responsive – that will be able to process the answers to disambiguation questions whenever they match the question, even if they start with verbs. The logic is essentially this: After reading the response, try it out as a response to the disambiguation question. If it works, process it. If it doesn’t work, try it out again as a new command. An extension that does this, with a bug that I think is fixable by someone who knows more I6 than me, is attached to this post. More detail underneath the spoiler.

[spoiler]At a bit more of a lower level, the logic is: Insert the response to the disambiguation into the original command, which is still in the player’s input buffer (this is how disambiguation requests are processed). Run the command. If it doesn’t produce a parser error, everything worked. If it does produce a parser error, things didn’t work, so re-process the response to the disambiguation command by copying it into the player’s input buffer, and reparse that.

Currently I have that mostly working; I’m using two flags to keep track of whether we’re processing an answer to a disambiguation request (and so should reroute parser errors to new commands). They probably aren’t both necessary but at least I haven’t set off into any infinite loops yet. Also the flags need to be reset on a successful parse; currently I’m doing this with a “first before” rule but there’s probably something safer in case a successful parse somehow doesn’t get to the Before rules (perhaps because of an “Understand as a mistake”?)

Worse yet, when the secondary input buffer is longer than the number of characters before the insertion point plus two, it produces buckets of Run-Time errors ("[** Programming error: tried to read from ->-1 in the array “buffer”, which has entries 0 up to 122 **]," one per every excess character). I’ve narrowed it down to this phrase:

To insert (length - a number) elements into (arr - a 1-based index based rulebook producing ZSCII letters) at (position - number): (- {-require-ctvs} ct_0 = {arr}; for (ct_1=INPUT_BUFFER_LEN-1 : ct_1 >= {position}+LETTER_ARRAY_BASE+1 : --ct_1) {arr}->ct_1 = {arr}->(ct_1 - ({length})); (+ the number of letters in the chosen array +) = (+ the number of letters in the chosen array +) + {length}; -).

and presumably somewhere I am failing to set an endpoint correctly. However, since I don’t understand I6, I can’t figure out how to fix it.[/spoiler]

In any case, this isn’t practical right now, aside from the bug; it depends on Ron Newcomb’s Original Parser extension (which is the current parser implemented in I7), and probably soon enough there will be a new parser with new behavior, and it’d be unreasonable for me to expect Ron to come up with a new I7 translation of it. But I think that it wouldn’t be too hard for someone who knows their way around the parser to code this behavior into it, and also figure out how I’ve managed to produce the run-time error.

So this isn’t so much an extension I expect anyone to use, but more of a proof of concept that we can make disambiguation more responsive if we want to provide that option. And also, if anyone can nail down that run-time error for me, that would be great!
Responsive Disambiguation.i7x (50.4 KB)

For what it’s worth:

The way I6 handles these cases is by a routine that matches the player’s command against a given set of dictionary words:

[ LanguageVerbMayBeName w; if (w == ’long’ or ’short’ or ’normal’ or ’brief’ or ’full’ or ’verbose’) rtrue; rfalse; ]; In I6, authors are presumably supposed to modify this routine (e.g. adding “or ‘go’” in the obvious place)

I understand, though, that you’re looking for a way to automatize the process, Matt. And this, of course, means hand coding it.

By the way the bug you mention seems to belong to Original Parser. At least it is produced by this code as well:

Include Original Parser by Ron Newcomb.

The Place is a room.
A go board is in place. A chess board is in place.

Include (- Replace LanguageVerbMayBeName; -) before "Language.i6t"

Include (- 
[ LanguageVerbMayBeName w;
    if (w == ’long’ or ’short’ or ’normal’
                     or ’brief’ or ’full’ or ’verbose’ or 'go')
-) after "Commands" in "Language.i6t"

Test me with "x board / chess / x board / go"

Well, not just that. If I can get Responsive Disambiguation to work (and then someone else can get it to work with the next parser), then it’ll be a bit more powerful because it’ll still allow “Go North” as a way of breaking out of the disambiguation question when it’s not a valid answer (which will be all the time). This might be particularly useful in Threaded Conversation, where it’d be easy to wind up with lots of valid verbs in the quips, and it might be annoying to treat them all as potential disambiguations all the time.

Hmm, you’re absolutely right. In fact you don’t have to do anything fancy to get this bug with Original Parser:

[code]Include Original Parser by Ron Newcomb.

Lab is a room. A buy chip and a sell chip are in Lab. A red block and a blue block are in Lab. A Go board and a chess board are in Lab.

Test me with “x board/chess”.[/code]

Roooooonnnnn! Halp!