Inform - Support - Patches

About Patches  

Compiler  
Library  

DM4 Errata  

Issue L60803

Failed disambiguation
Submitted by: Ethan Dicks     Appeared in: Library 6/8     Fixed in: Library 6/10
Problem

I have a problem with the 6/8 library: I was using ChooseObjects to differentiate between the "east" direction and an "eastern wall" in a certain well known puzzle, and now it breaks. To wit:

Old lib (trace 4 in effect)

  >PUSH EAST
  [ "push" push / "east" east ]
  [Parsing for the verb 'push' (3 lines)]

  [line 0 * noun -> Push]
   [line 0 token 1 word 2 : noun]
    [Object list from word 2]
    [Calling NounDomain on location and actor]
     [NounDomain called at word 2
     seeking definite object
     [ND made 2 matches]
     [Adjudicating match list of size 2 in ...
     definite object
     ML: east wall  initial score 0
     ML: eastern wall  initial score 0
     Scoring match list: indef mode 0 type 0...
     The east wall (9) in the compass scores...
     The eastern wall (312) in the Room in a...
     Difficult adjudication with 2 ...
     The east wall (9)  ---  1
     The eastern wall (312)  ---  2
     ChooseObjects picked a best.]
    [ND returned the eastern wall]
    [token resulted in success]
   [line 0 token 2 word 3 : END]
  [Line successfully parsed]
  The wall slides forward and you follow it
  to this position:

New lib (trace 4 in effect)

  >PUSH EASTRNING
  [ "push" push / "east" east ]
  [Parsing for the verb 'push' (3 lines)]

  [line 0 * noun -> Push]
   [line 0 token 1 word 2 : noun]
    [Object list from word 2]
    [Calling NounDomain on location and actor]
     [NounDomain called at word 2
     seeking definite object
     [ND made 2 matches]
     [Adjudicating match list of size 2 in ...
     definite object
     Scoring match list: indef mode 0 type 0...
       The east wall (9) in the compass : ...
       The eastern wall (312) in the Room in...
     Single best-scoring object returned.]
    [ND returned the east wall]
    [token resulted in success]
   [line 0 token 2 word 3 : END]
  [Line successfully parsed]
  (the east wall)
  The Room in a Puzzle isn't open.

Two problems: "push eastrning" (the previous object word was 'warning') and the lack of further effort on the part of the parser if there is a single best-scoring object". Did something change and ChooseObjects() fall from favor? Is this an oversight?

Solution (by Neil Cerutti)

In library 6/8 the ChooseObjects() entry point routine fell from favor. This is how ChooseObjects() is supposed to work, as documented in this excerpt from the DM:

"The other circumstance is when code is 2. This means the parser is sorting through a list of items (those in scope which best matched the input), trying to decide which single one is most likely to have been intended. If it can't choose a best one, it will give up and ask the player. ChooseObjects should then return a number from 0 to 9 (0 being the default) to give the object a score for how appropriate it is."

In library 6/8, right after ScoreMatchL() is called, Adjudicate() returns the single best scoring object. ChooseObjects() can contribute between 0 and 9 points to the score an object receives. The problem with this is that 0-9 points is seldom enough to override the scores awarded by the library, which are generally between 40 (undesirable objects, i.e. concealed) and 160 (desirable objects), but can climb to over 1000 for certain extreme preferences (i.e. ##Take objects that you aren't carrying). The result is that in library 6/8, ChooseObjects() is subservient to the library's decisions.

In Ethan's case, the eastern wall object he created is probably concealed, while the compass objects are not (they are scenery). This results in the large scoring difference -- which cannot be compensated for with ChooseObjects().

In the library 6/7 Adjudicate() routine, the ChooseObjects() routine was bequeathed complete authority. It was called for all the matched objects, and the object that received the hightest return value ([0-9]) was chosen (Parserm.h, lines 2446-2466). In library 6/7, Adjudicate() only returned the single highest scoring object as a last resort, using the BestGuess() routine (called at the end of Adjudicate()).

My solution is to replace the SingleBestGuess routine with the following:

  [ SingleBestGuess  earliest its_score best i j k best_count;

  ! Begin code added (adapted from lines 2446-2466 in library 6/7
  ! parserm.h, Adjudicate routine).
  ! j, k, and best_count are new local variables used by this code.

    j=0; best_count=0;
    for (i=0 : i < number_matched : i++)
    {   k=ChooseObjects(match_list-->i,2);
        if (k==j) best_count++;
        if (k>j)
        {   j=k; best_count=1;
            best=match_list-->i;
        }
    }
    if (best_count==1)
    {
  #ifdef DEBUG;
        if (parser_trace>=4)
            print "    ChooseObjects determined best match^";
  #endif;
            return best;
    }

  ! End code added.

    earliest=-1; best=-1000;
    for (i=0:i<NUMBER_MATCHED:I++) { its_score="match_scores--">i;
        if (its_score==best) earliest = -1;
        if (its_score>best)
        {   best=its_score;
           earliest=match_list-->i;
        }
    }
    return earliest;
  ];

This change returns ChooseObjects() to its former utility and glory.


Last updated 17 April 2013. This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation. Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Roger Firth.