Bug 0001160 - "drop x on down" [Patch available inside]

Start up your favourite piece of Inform 7 IF, pick up a few items, then find a supporter like a table to put it on, and then type “drop x on down” to put item x… …where? On down? Yes, why not?
You’ll get a question like "What do you want to drop " followed by some gibberish - for example “What do you want to drop the apple the keyring?” or “What do you want to drop the stone those things?”.
Try to answer that question however you like, and you’ll get an outcome similar to “I only understood you as far as wanting to drop the apple on down.”.

I won’t act like I haven’t already patched this bug, and have a theory as to why the bug existed in the first place, but I feel that I need to run this by you, because maybe I’m blameing the wrong reasons for Inform 7 acting like this. Are there more bugs like this that I need to be aware of? Try to contribute to solving this “christmas mystery”, and I’ll post my code for the patch in a few posts. =)

I can’t reproduce this.

The Kitchen is a room.
The player carries a rock.
The table is a supporter in the Kitchen.

Result:

Yes, it works perfectly fine until you pick up another item. You need more than one item to choose from (and I don’t know why).

I could not reproduce the bug either.

The kitchen is room. The table is a supporter in the kitchen. The player carries a rock and an apple.
>put rock on down
You must name something more substantial.

Strange. I’ll get back to you once I’ve isolated what makes this happen, because right now I have a bunch of extensions messing with the grammar.

Draconis, actually you can replicate it indeed with the code you posted. But the syntax that makes it appear is not “put”, but “drop”.

Same source code as you posted.

"kitchen
You can see a table here.

drop rock on down
What do you want to drop the rock on those things?"

EDIT - Hello hello hello, the bug only appears once, on the first move.

EDIT 2 - Well, actually no, the actual bug always appears, but we only get gibberish on the first move.

Replicated successfully with Peter’s syntax. This is very odd.

Yes, the more I look at it, the more I feel that my patch is just covering up the symptoms of a bug deeper in the core, but I discovered this bug when I saw the rules specifically mentioning “down” in the rules for “putting it on” and “inserting it into”. …but if it would just involve those two simple rules, “drop stone down down”, or even “put stone on down”, would reasonably result in errors, but it turns out that it doesn’t. …and why does it only trigger when I have more than one items in my inventory?

Very well, here’s my patch:


Section - drop x on down

[The standard rules list two faulty check rules, that results in bad grammar for the putting it on action in combination with multiple carried objects.
The rules are named "convert put to drop where possible" and "convert insert to drop where possible".
A likely explanation is that they were both written to handle "put [things preferably held] [something]", but since then the grammar got changed to "put [things preferably held] down" being directly interpreted as dropping.
The only apparent effect in-game, is that "drop [other things] on down" results in a question like "What do you want to drop x those things?" (to which there doesn't seem to be a correct reply).
]


The new convert put to drop where possible rule is listed instead of the convert put to drop where possible rule in the check putting it on rulebook.

Check an actor putting something on (this is the new convert put to drop where possible rule):
	If the actor is on the second noun,
		convert to the dropping action on the noun.


The new convert insert to drop where possible rule is listed instead of the convert insert to drop where possible rule in the check inserting it into rulebook.

Check an actor inserting something into (this is the new convert insert to drop where possible rule):
	If the actor is in the second noun,
		convert to the dropping action on the noun.

Thanks for posting the working example code. I mean, the not-working example code.

I have not yet had a chance to look into this. However, I can give some history.

The Inform grammar has never included “put [things preferably held] [something]”. It does include “put [things] down” and “put down [things]”, which already handle that case without any action-conversion rule.

Inform used to include “floor” as a synonym for “down”, so I’m sure this rule is intended to cover “put rock on floor”.

However, “floor” isn’t a synonym for “down” any more. Also, the “You must name something more substantial” error has been added for commands like “take north”. I believe this error happens before check rules, so it should supersede the “put rock on down” case. In other words, the conversion rules really have no reason to handle the “down” case any more.

However again – this should not lead to confusing parser output. It should reliably say “You must name something more substantial”. I’ll have to dig into what’s going on there.

Did some more testing. I’m afraid your patch doesn’t affect the bug at all. Which makes sense – the bug appears before the “check” action phase.

I’ve filed a bug: inform7.com/mantis/view.php?id=1160 . The bug is in an obscure chunk of preposition-handling code. I don’t have a patch; sorry.

(The word “down” turns out to be a red herring – the down direction has nothing to do with the bug at all. You can see the same symptom by typing “drop rock on into”.)

Kinda makes this look like an IF puzzle, the red herring.

And worse yet, it seems to be annoyingly underclued. I wish I7 had an adaptive hint system…

Hate to tell you, but debugging can be like a puzzle in any piece of software.

I thought that’d be your reply. :wink:

The only thing that I can add (as I am away from I7 at the moment) is that it looks to me like it doesn’t get that words like “down” and “into” is supposed to count as the second noun in the sentence, instead of something that’s just for grammar’s sake - maybe the grammar is misleading it. …so the interpreter begins to look for the “missing” second noun, and ends up adding a third noun to the sentence, which it then objects against having. That’s my best guess.

I put some details in the bug report. It’s technical, it’s incrementing too far when looping through the array of words. I’m not sure of the logic in that chunk of code, but it’s trying to read word five of “drop rock on into” so it’s obviously not right.

Good news: Graham says the bug “is” fixed now (for future I7 versions, no doubt), and he also provided us with just the bare information for making a patch too. I’m posting it below in I7 extension form, so that you can just copy and paste it.
Note that I might have misinterpreted where the fix should be applied, because there are THREE places where “l = NextWord();” is part of a do…while loop. If you are still experiencing problems after including this patch, post either here or at the bug report site.

Bug 0001160 Patch by Graham Nelson begins here.
"This patch fixes bug 0001160."


Include (-
advance_warning = -1; indef_mode = false;
for (i=0,m=false,pcount=0 : line_token-->pcount ~= ENDIT_TOKEN : pcount++) {
	scope_token = 0;
	if (line_ttype-->pcount ~= PREPOSITION_TT) i++;
	if (line_ttype-->pcount == ELEMENTARY_TT) {
		if (line_tdata-->pcount == MULTI_TOKEN) m = true;
		if (line_tdata-->pcount == MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN && i == 1) {
			! First non-preposition is "multiexcept" or
			! "multiinside", so look ahead.
			#Ifdef DEBUG;
			if (parser_trace >= 2) print " [Trying look-ahead]^";
			#Endif; ! DEBUG
			! We need this to be followed by 1 or more prepositions.
			pcount++;
			if (line_ttype-->pcount == PREPOSITION_TT) {
				! skip ahead to a preposition word in the input
				do {
					l = NextWord();
				} until ((wn > num_words) ||
					(l && (l->#dict_par1) & 8 ~= 0));
				if (wn > num_words) {
					#Ifdef DEBUG;
					if (parser_trace >= 2)
						print " [Look-ahead aborted: prepositions missing]^";
					#Endif;
					jump LineFailed;
				}
				do {
					if (PrepositionChain(l, pcount) ~= -1) {
						! advance past the chain
						if ((line_token-->pcount)->0 & $20 ~= 0) {
							pcount++;
							while ((line_token-->pcount ~= ENDIT_TOKEN) &&
								((line_token-->pcount)->0 & $10 ~= 0))
								pcount++;
						} else {
							pcount++;
						}
					} else {
						! try to find another preposition word
						do {
							l = NextWord();
						} until ((wn >= num_words) ||
							(l && (l->#dict_par1) & 8 ~= 0));
						if (l && (l->#dict_par1) & 8) continue;
						! lookahead failed
						#Ifdef DEBUG;
						if (parser_trace >= 2)
							print " [Look-ahead aborted: prepositions don’t match]^";
						#endif;
						jump LineFailed;
					}
					! BUG 0001160 PATCH BEGIN
					! Old line was 'l = NextWord();'.
					if (wn <= num_words) l = NextWord();
					! BUG 0001160 PATCH END
				} until (line_ttype-->pcount ~= PREPOSITION_TT);
				! put back the non-preposition we just read
				wn--;
				if ((line_ttype-->pcount == ELEMENTARY_TT) &&
					(line_tdata-->pcount == NOUN_TOKEN)) {
					l = Descriptors(); ! skip past THE etc
					if (l~=0) etype=l; ! don’t allow multiple objects
					k = parser_results-->INP1_PRES; @push k; @push parameters;
					parameters = 1; parser_results-->INP1_PRES = 0;
					l = NounDomain(actors_location, actor, NOUN_TOKEN);
					@pull parameters; @pull k; parser_results-->INP1_PRES = k;
					#Ifdef DEBUG;
					if (parser_trace >= 2) {
						print " [Advanced to ~noun~ token: ";
						if (l == REPARSE_CODE) print "re-parse request]^";
						else {
							if (l == 1) print "but multiple found]^";
							if (l == 0) print "error ", etype, "]^";
							if (l >= 2) print (the) l, "]^";
						}
					}
					#Endif; ! DEBUG
					if (l == REPARSE_CODE) jump ReParse;
					if (l >= 2) advance_warning = l;
				}
			}
			break;
		}
	}
}
! Slightly different line-parsing rules will apply to "take multi", to
! prevent "take all" behaving correctly but misleadingly when there’s
! nothing to take.
take_all_rule = 0;
if (m && params_wanted == 1 && action_to_be == ##Take)
	take_all_rule = 1;
! And now start again, properly, forearmed or not as the case may be.
! As a precaution, we clear all the variables again (they may have been
! disturbed by the call to NounDomain, which may have called outside
! code, which may have done anything!).
inferfrom = 0;
parameters = 0;
nsns = 0; special_word = 0;
multiple_object-->0 = 0;
etype = STUCK_PE;
wn = verb_wordnum+1;
-) instead of "Parser Letter F" in "Parser.i6t".



Bug 0001160 Patch ends here.

---- DOCUMENTATION ----

This is a quick fix for a bug when typing grammar like "drop x on down".
I made this extension based on information from Graham Nelson.
The bug is described here: http://inform7.com/mantis/view.php?id=1160
The bug is further discussed here: https://intfiction.org/t/bug-0001160-drop-x-on-down-patch-available-inside/6151/1