Bug? Topic-based actions not parsed if they share a verb word with another action

One issue that remains unresolved by the above fixes is that the parser has no simple way of recognising that a new command in the form of a ‘no.verb’ grammar line has been typed at a disambiguation prompt in lieu of an answer to the disambiguation question. The present parser code relies on finding one of: a (genuine) verb as the first word; or a verb being returned by LanguageIsVerb() (if defined); or the presence of a comma somewhere in what is typed to suggest a new attempt at conversation in the form ‘Someone, …’ (which is why test case [11] works ok); in order to divert entry at the disambiguation prompt to parsing a new command rather than disambiguating the last.

Consequently, typing ‘use fork’ at a disambiguation prompt leads to ‘use fork’ being inserted into the previous command as an answer to the disambiguation question and an attempt at reparsing something like ‘take use fork walnut’, usually with ‘I didn’t understand that sentence’ as a result. I can’t see a simple solution to this: although irritating it’s unlikely to cause much of an issue in practice.

Another edge case for which a fix is provided below arises when issuing a chain of commands to an NPC. verb_wordnum now ‘sits upon’ the comma after processing ‘no.verb’ commands such as the first in ‘Darcy, use knife. take fork’. The code that erases the processed first command from the input buffer before moving on to parse the second starts from verb_wordnum, so erases the comma too, leading to an attempt to parse ‘darcy take fork’ and therefrom to ‘I did not understand that sentence.’

The fix below nudges verb_wordnum forward by one, past the comma, to deal with this case.
NB the location of the erasure code was moved at some point from Parser Letter K to Parser Letter A so this fix (at least insofar as it is included before Parser Letter A) is only guaranteed to work for Inform 6M62

As a bonus, I’ve included a fix for another issue I came across in testing, whereby an attempt to test for an included text in a zero-length snippet throws a programming error, unless the snippet is of numeric value 100, which is special-cased. I’m not sure why 200, 300 etc. aren’t included in this special-casing, but the issue came to light because ‘darcy,’ generates a topic understood of “” represented by a snippet of numeric value 300.

"___Fix_Verbless_Actions Ver2" by PB

Chapter - Setup

Section - Setting up so UnknownVerb() returns 'no.verb' and 'employ' is ambiguous as a verb or 'no.verb'

To handle is a verb. To strut is a verb.
Understand "employ subterfuge/deceit/deception/wiles" as deceiving.
Understand "employ/deploy/utilise/use" as "[utilising]".
Understand "[utilising] [something]" as using.
Using is an action applying to one thing.
Deceiving is an action applying to nothing.
Report an actor deceiving: say "[The actor] [strut] around the room, maintaining a pretence of indifference to [their] surroundings.".
Report an actor using: say "[The actor] [handle] [the noun] with the accomplishment born of faultless breeding.".

Chapter - Fix (Inform 6_34)

Section - Fix for incorrect snippet generation when UnknownVerb() returns 'no.verb' and command of form 'Darcy, splendid coat' is diverted to ##Answer, by correct reset of verb_wordnum

Include (- Replace UnknownVerb; -) after "Definitions.i6t". [run our new routine instead]
Include (- [UnknownVerb; verb_wordnum--; return 'no.verb'; ]; -) [move verb_wordnum back to 0 if still searching for verb as first word of command, or back to the comma if a command like 'Darcy, ....'] after "Output.i6t". [make sure it comes after the original UnknownVerb in the output I6. (- Replace MyFunction [OldMyFunction]; -) must precede any declaration of MyFunction() but may be followed by any number of subsequent declarations of MyFunction(). The MyFunction chosen to compile will be the last-defined version, except that definitions in normal files are always preferred over definitions in System_file files or the veneer. With the two-parameter form (introduced in 6.33), the declaration chosen to be renamed and compiled as OldMyFunction will be the first-declared version of the function.]

Section - Fix for comma being erased from chained commands to NPC following a 'no.verb' command (eg test case [11]) by nudging verb_wordnum forward by 1, past the comma

Include (-
if ((held_back_mode) && (verb_wordnum ~=0)){
	wn = verb_wordnum;
	if (NextWordStopped() == comma_word) verb_wordnum++;
};
-) before "Parser Letter A" in "Parser.i6t".	  

Section - Fix for failure to consider 'no.verb' grammar lines when no grammar lines match for a detected verb

[if we've reached this point all grammar lines for the recognised verb have failed, so if we haven't tried 'no.verb' and UnknownVerb() returns 'no.verb'- indicating at least some 'no.verb' grammar lines, try those]

Include (- if ((verb_word ~= 'no.verb') && (verb_word =UnknownVerb(verb_word))) jump VerbAccepted; -) after "Parser Letter G" in "Parser.i6t".

Section - Bonus Fix  Inappropriate RTP error generated by 'when the topic understood includes __' when the topic understood is "" eg after 'Darcy,' which generates ##Answer action with parsed_number 300

Include (- Replace SnippetIncludes; -) after "Definitions.i6t".

Include (- 

[ SnippetIncludes test snippet w1 w2 wlen i j;
	w1 = snippet/100; w2 = w1 + (snippet%100) - 1;
	if ((w2<w1) || (w1<1)) {
		if ((w1 == 1) && (w2 == 0)) rfalse; ! #### pre-existing special-case for snippet of 100
		! ##### Insertion
		!print "w1=",w1," w2=",w2,"^";
		if ((snippet%100) == 0) rfalse;  ! 100, 200, 300 etc. i.e. snippet is ""
		! ##### Insertion ends
		return RunTimeProblem(RTP_INCLUDEINVALIDSNIPPET, w1, w2);
	}
	if (metaclass(test) == Routine) {
		wlen = snippet%100;
		for (i=w1, j=wlen: j>0: i++, j-- ) {
			if (((test)(i, 0)) ~= GPR_FAIL) return i*100+wn-i;
		}
	}
	rfalse;
];
-) after "Output.i6t".


Chapter - Scenario

Netherfield Hall is a room. "A soaring space of oak-panelled grandeur, with a small doorway to the north.".
The workbench is here. The sideboard is here. The walnut box is a closed opaque openable container. it is on the workbench. The teatray is a portable supporter. It is on the sideboard. The teapot is on the teatray. The hat is a wearable thing. It is on the workbench. A Walnut Whip is an edible thing in the box. The knife, the fork, the apple, the salad server and the cruets are on the sideboard. Cutlery is a kind of thing. The knife and fork are cutlery. The apple is edible. The cruets are plural-named. The thingumajig is nowhere. In Netherfield Hall is a man called Mr Darcy. Darcy is proper-named. Mr Darcy wears a blue frock coat. The initial appearance of Mr Darcy is "Mr Darcy haughtily haunts the hall." In Netherfield Hall is a woman called Miss Elizabeth Bennett. The printed name of Elizabeth is "Miss Bennett". Elizabeth is proper-named. Elizabeth wears a shawl.  The initial appearance of Elizabeth is "Miss Bennett sits demurely, while her glance flits penetratingly over her surroundings." The cupboard is an open, opaque, openable, enterable, fixed in place container. It is in Netherfield Hall.
There is an open door called the parlour door.  The indefinite article of parlour door is "the". There is a room called The Parlour. It is north of the parlour door.  The parlour door is north of Netherfield Hall. The plucked pheasant is in the Parlour.  The oak shelving is a backdrop. It is not scenery. The shelving is in the Parlour and Netherfield Hall. The indefinite article of the shelving is "some". Netherfield Park is a region. Netherfield Hall and the Parlour are in Netherfield Park.

The player carries an animal called the hamster. The player wears a pair of glasses. The glasses are plural-named. The indefinite article of the glasses is "a". The player carries a closed openable transparent container called the glass jam jar. The starfish is an animal. It is in the glass jam jar.


Chapter - Testing

Section - Machinery
	
Persuasion: rule succeeds.

Instead of answering Miss Bennett that when the topic understood includes "netherfield": say "Charming, [if Mr Darcy is in the location]is it not, Darcy[else] don't you agree[end if]?".
To regard is a verb.
Instead of answering Darcy that when the topic understood includes "collins": say "[Mr Darcy] [regard] [us] silently, with an exquisitely pained expression.".

Section - Test Scripts

Test me with "Darcy, I believe Mr Collins has had the remarkable good fortune to shoot a peacock / use fork / employ deceit / Miss Bennett, what is your opinion of Netherfield? / Darcy, employ subterfuge / Elizabeth, employ the salad server / darcy, open box / take walnut / use fork / darcy, take walnut / darcy, use fork. use knife / elizabeth, take walnut / elizabeth, employ wiles / darcy,".

[unfixed problems:
	(i) 'no.verb' typed at a disambiguation prompt e.g. 'use fork' in test case [9] leads to a command with 'use fork' inserted at the disambiguation point being passed to the parser, e.g. 'take use fork walnut']