adv3Lite disambigName suggestion

It appears disambigName is only printed if the name properties of two objects are actually identical. This is usually sensible enough. But I happen to have a cooler in which are some six-packs of beer, from which the player can remove a single six-pack. This leads to the following output:

And because adv3Lite is cheerfully willing to understand implied plurals, that type of message may be difficult for the player to deal with. At the very least, it looks like a guess-the-noun problem, even though it’s not.

Would it be practical for the parser to use disambigName if it is defined on the object, rather than only when it’s specifically needed? Or would that cause other problems?

As I understand it your cooler contains an object representing several six packs of beer, and when the player tries to take a six pack of beer, a separate six pack of beer object is moved into scope. Both objects now respond to ‘six-packs of beer’ because the parser automatically implies the plural of ‘six-pack of beer’.

I confess the first time I read your post I didn’t understand how your proposal would meet the problem, but on re-reading I think what you mean is that you could get round your problem if the parser used the disambigNames in this situation (since you could make them more meaningful), but it’s not doing so because the name properties aren’t identical. This is certainly something I can take a look at. The current behaviour wasn’t of my design; it’s something advLite has inherited from Mike Roberts’s Mercury parser code (and in a part of it I haven’t really looked at that closely, since up until now it seemed to be working fine). I would have thought the more useful behaviour would be to have the disambigName default to the name, and for the parser always to use the disambigName when disambiguating (which would more or less have the effect you were suggesting), but there may be some reason for not doing it this way, and a quick look at Mike’s code suggests to me that it may not be trivial to achieve.

So, I think there may be an issue for me to look at here, but until I’ve had a chance to look into it further (and it’s clearly not going to be a five-minute job), I’m not sure what the right answer is.

In the meantime, there are a number of other possible ways round your particular problem that you may want to consider:

(1) Since your cooler can presumably contain only a finite number of six-packs, you could define a SixPack class and put, say, a dozen instances of it in your cooler. This would represent the actual situation I assume you’re trying to model in the simplest and most direct way, and dispenses with the need for a separate six-packs (plural) object. It’s a possible solution here since the total number of six-packs that are realistically likely to exist is quite low (it would not work so well for a bunch of grapes and individual grapes, but that’s not what you’re trying to model).

(2) Alternatively, you could stop the six-pack (singular) object matching the plural (six-packs) by giving it some other plural the player would never type, e.g. ‘six-pack[-zz]’. This is essentially the solution employed in an analogous solution in the Airport game example in the adv3Lite Tutorial.

(3) Another possibility would be to give one or other object a vocabLikelihood of 10, say, so that the parser would always prefer it to the other when both were in scope (thus avoiding the disambiguation question altogether).

(4) It may be that making the six-packs (plural) a CollectiveGroup would help, since this would enable you do define which actions were handled by the CollectiveGroup object and which by its members (in this case the single six-pack).

This raises more general questions about collective/individual dispenser/dispensed type disambiguation that I’ll need to put some more thought into, alongside your disambigName suggestion.

Thanks – using vocabLikelihood and a dummy plural (I think using curly braces, not square brackets as you indicated above) solves the immediate problem.

I intend the player to be able to extract only one six-pack from the cooler, so creating a class and a CollectiveGroup would be extra overhead.

I’ve now taken a look at your original disambigName suggestion and realized it’s a special case of a wider potential problem. Suppose you had a game that included the following object definitions:

+ redBall: Thing 'red ball'
;

+ bigBall: Thing 'ball'
    disambigName = 'big ball'
;

As things stand, because these objects have different names, a command like X BALL will result in the question “Which do you mean, the red ball or the ball?” even though the bigBall has a disambigName. The solution I’ve adopted is to change the parser’s notion of what counts as different names in this situation. In particular I’ve changed the nameDistinguisher to this:

/*
 *   The basic name distinguisher distinguishes objects by their base names.
 *   This is the first distinguisher we apply, since the name is always the
 *   easiest way to tell objects apart in parsing. However since one name could
 *   be entirely contained within another (e.g. 'ball' and 'red ball') we
 *   consider the names as equal for this purpose if one of them is part of the
 *   other.
 */
nameDistinguisher: Distinguisher
    sortOrder = 100
    equal(a, b) { return a.name.find(b.name) || b.name.find(a.name); }
;

It’s possiblt to construct situations where this will result in the use of disambigName where they are not strictly necessary, but I suspect they will be few and far between, e.g. the response to X RED when we have:

+ Thing 'red ant; scary'
   disambigName = 'scary red ant'
;

+ Thing 'red antelope; fast'
    disambigName = 'fast red antelope'    
;

The other (Dispsenser/Dispensed) problem will require furhter thought.