intfiction.org

The Interactive Fiction Community Forum
It is currently Wed Jun 19, 2013 8:06 am

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Tue Jul 31, 2012 3:27 pm 
Offline
User avatar

Joined: Sun Nov 22, 2009 12:58 pm
Posts: 402
Location: Malmö, Sweden
This is a problem I've seen before, but I've never isolated it before now. And it's become a problem.

Code:
DNA is a kind of thing. Some skin is a kind of thing. Some DNA and some skin is part of every person.

Felix is a man.
Dr Wilbur is a man.
The Lab is a room. Wilbur is here. The player is Felix.

After asking Wilbur about "[DNA]", say "'Your genetic code has somehow been altered.'"
After asking Wilbur about "[skin]", say "'Yes, that was where I scraped off some DNA for my sample.'"

Test me with "ask wilbur about wilbur's DNA/ask wilbur about wilbur's skin".


For some reason, whenever I ask about something created as part of an assembly, only the first After rule (or Instead rule) that applies to said parts is matched. Am I doing something terrifying and/or wrong, is this a bug, or have I just utterly lost my marbles? Anyone know?

_________________
~Björn Paulsen


Top
 Profile Send private message  
 
PostPosted: Tue Jul 31, 2012 6:09 pm 
Offline

Joined: Tue Jan 11, 2011 8:19 pm
Posts: 21
The After and Instead rulebooks have default outcomes "rule succeeds" and "rule fails," respectively. Most other common rulebooks use the default "make no decision." The difference is exactly as you describe: when a rule in After or Instead applies, and it doesn't specifically make no decision, processing of the rulebook stops at that point (there is no meaningful difference between "rule fails" and "rule succeeds" in these situations).


Top
 Profile Send private message  
 
PostPosted: Tue Jul 31, 2012 6:41 pm 
Offline
User avatar

Joined: Thu Nov 04, 2010 6:30 am
Posts: 999
Location: Gothenburg, Sweden
I don't think you're doing anything wrong.

It seems that even after the parser has identified Wilbur's skin as the relevant object, it still tries to apply the first 'After asking Wilbur about [TOPIC]' rule to that object.

There's apparently an I6 routine called ConsultNounFilterToken that tests if the rule (or possibly some other routine) is applicable on the skin and decides it isn't. That's why the block asking rule is applied instead. And if you force a positive answer from ConsultNounFilterToken, asking wilbur about Wilbur's skin will trigger the 'after asking Wilbur about "[DNA]"' rule! (Because it's the first 'After asking wilbur about [TOPIC]' rule defined in your source, I bet.)

I have no idea why this is so, however, or what to do about it. Perhaps the Original Parser extension is just hackable enough to help ...

_________________
Man ska inte tro allt man tänker.


Top
 Profile Send private message  
 
PostPosted: Tue Jul 31, 2012 11:16 pm 
Offline

Joined: Tue Jul 17, 2012 5:06 pm
Posts: 17
I think it might be a bug.

If you crank up the debug output using "trace 6" and enter "ask wilbur about wilbur's skin", it looks like the parser is rejecting the match it makes on "wilbur's skin" even though it initially seems to identify it as a higher-quality match:

Quote:
[DSA on Dr Wilbur's DNA with reason = 0 p1 = 0 p2 = 0]
Trying Dr Wilbur's DNA (49) at word 4
Matched (1)
Match with quality 1
Match added to list
[DSA on Dr Wilbur's skin with reason = 0 p1 = 0 p2 = 0]
Trying Dr Wilbur's skin (50) at word 4
Matched (2)
Match with quality 2
Match filtered out: token filter -29354
[ND made 1 matches]
[ND returned Dr Wilbur's DNA]

There is no reply.


If you look at the generated I6 file, you can see that it is creating separate Consult_Grammar_N functions using separate Noun_Filter_N functions for each of the after rules created. Following are some excerpts from auto.inf when I compiled your sample code:

Code:
! ----------------------------------------------------------------------------------------------------
! Rules in rulebook: After (B24_after)
! ----------------------------------------------------------------------------------------------------
! Rule 1/2 ! After asking Wilbur about ~[DNA]~:
!   === which is equally specific with ===
! Rule 2/2 ! After asking Wilbur about ~[skin]~:
! ----------------------------------------------------------------------------------------------------
! No specific request
! After asking Wilbur about ~[DNA]~:
[ R_740 ;
   if ((action ==##Ask) &&  (actor==player) && ((noun == I95_dr_wilbur) && (true)) && (Consult_Grammar_100(consult_from, consult_words)~=GPR_FAIL)) { ! Runs only when pattern matches
self = noun;
   if (debug_rules) DB_Rule(R_740, 740);
      ! phrase 1
      ! [1: say ~'Your genetic code has somehow been altered.'~]
      say__p=1;ParaContent();  print (PrintText) SC_12;  new_line; .L_Say3; .L_SayX3;
      RulebookSucceeds(); rtrue;
   } ! Runs only when pattern matches
   else if (debug_rules > 1) DB_Rule(R_740, 740, true);
   rfalse;
];
! No specific request
! After asking Wilbur about ~[skin]~:
[ R_741 ;
   if ((action ==##Ask) &&  (actor==player) && ((noun == I95_dr_wilbur) && (true)) && (Consult_Grammar_101(consult_from, consult_words)~=GPR_FAIL)) { ! Runs only when pattern matches
self = noun;
   if (debug_rules) DB_Rule(R_741, 741);
      ! phrase 1
      ! [1: say ~'Yes, that was where I scraped off some DNA for my sample.'~]
      say__p=1;ParaContent();  print (PrintText) SC_13;  new_line; .L_Say4; .L_SayX4;
      RulebookSucceeds(); rtrue;
   } ! Runs only when pattern matches
   else if (debug_rules > 1) DB_Rule(R_741, 741, true);
   rfalse;
];
! ----------------------------------------------------------------------------------------------------

[ Consult_Grammar_100
    range_from  ! call parameter: word number of snippet start
    range_words  ! call parameter: snippet length
    original_wn  ! first word of text parsed
    group_wn  ! first word matched against A/B/C/... disjunction
    w  ! for use by individual grammar lines
    rv  ! for use by individual grammar lines
    ;
    wn = range_from; original_wn = wn; rv = GPR_PREPOSITION;
        w = ParseTokenStopped(ROUTINE_FILTER_TT, Noun_Filter_4);
        if (w == GPR_FAIL) jump Fail_1; rv = w;
        if ((range_words==0) || (wn-range_from==range_words)) return rv;
        .Fail_1; rv = GPR_PREPOSITION; wn = original_wn;
    return GPR_FAIL;
];

[ Consult_Grammar_101
    range_from  ! call parameter: word number of snippet start
    range_words  ! call parameter: snippet length
    original_wn  ! first word of text parsed
    group_wn  ! first word matched against A/B/C/... disjunction
    w  ! for use by individual grammar lines
    rv  ! for use by individual grammar lines
    ;
    wn = range_from; original_wn = wn; rv = GPR_PREPOSITION;
        w = ParseTokenStopped(ROUTINE_FILTER_TT, Noun_Filter_5);
        if (w == GPR_FAIL) jump Fail_1; rv = w;
        if ((range_words==0) || (wn-range_from==range_words)) return rv;
        .Fail_1; rv = GPR_PREPOSITION; wn = original_wn;
    return GPR_FAIL;
];
[ Noun_Filter_4 x;
    x=noun;
    return ((noun ofclass K16_dna));
];
[ Noun_Filter_5 x;
    x=noun;
    return ((noun ofclass K17_skin));
];


So it looks like it *wants* to do what you're asking it to, but when it's evaluating rules, it seems to skip over whichever after rule is defined second. I'm not really sure why.

One thing you might not have intended: You'll get the same response whether you ask about "felix's dna" or "wilbur's dna".


Top
 Profile Send private message  
 
PostPosted: Wed Aug 01, 2012 2:58 am 
Offline
User avatar

Joined: Sun Nov 22, 2009 12:58 pm
Posts: 402
Location: Malmö, Sweden
otistdog wrote:
I think it might be a bug.

<snip>

So it looks like it *wants* to do what you're asking it to, but when it's evaluating rules, it seems to skip over whichever after rule is defined second. I'm not really sure why.

One thing you might not have intended: You'll get the same response whether you ask about "felix's dna" or "wilbur's dna".


Thanks. And yeah, I did intend to get the same results, because I want to match the topic of DNA in general. In this kind of conflict we get entire subjects that are no longer recognized as topics, and that's annoying (not to mention fatal to my project).

EDIT: Reported it as a bug.

_________________
~Björn Paulsen


Top
 Profile Send private message  
 
PostPosted: Wed Aug 01, 2012 12:03 pm 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 2127
I added a bug comment. The problem is that matching the "[DNA]" topic corrupts the noun global variable, which screws up the rest of the action rulebook. It's definitely a bug.

Lest we go too far down the wrong path, let me note that there's no problem doing it the simple way:

After asking Wilbur about "DNA": ...
After asking Wilbur about "skin": ...


Top
 Profile Send private message  
 
PostPosted: Wed Aug 01, 2012 2:14 pm 
Offline

Joined: Fri Jul 16, 2010 2:09 pm
Posts: 1951
I've never liked the way topics are handled - which is why I prefer to use a conversation extension that deals with objects instead. But my Objects Matching Snippets extension is intended to serve as a middle ground, for cases like this:

Quote:
> Wilbur, DNA


where the comma prevents the command from being interpreted as a keyword.

I'm currently working on an acceleration for it, as it is quite slow.


Top
 Profile Send private message  
 
PostPosted: Wed Aug 01, 2012 5:11 pm 
Offline
User avatar

Joined: Thu Nov 04, 2010 6:30 am
Posts: 999
Location: Gothenburg, Sweden
Here's a fix (and I added a note about it to the bug report):
Code:
Include (-

[ MakeMatch obj quality i;
#Ifdef DEBUG;
if (parser_trace >= 6) print "
Match with quality ",quality,"^";
#Endif; ! DEBUG
if (token_filter ~= 0 && ConsultNounFilterToken(obj) == 0) {
!print token_filter; print "^"; print (name)obj; print": "; print ConsultNounFilterToken(obj); print "^";
#Ifdef DEBUG;
if (parser_trace >= 6) print "
Match filtered out: token filter ", token_filter, "^";
#Endif; ! DEBUG
rtrue;
}
if (quality < match_length) rtrue;
if (quality > match_length) { match_length = quality; number_matched = 0; }
else {
if (number_matched >= MATCH_LIST_WORDS) rtrue;
for (i=0 : i<number_matched : i++)
if (match_list-->i == obj) rtrue;
}
match_list-->number_matched++ = obj;
#Ifdef DEBUG;
if (parser_trace >= 6) print "
Match added to list^";
#Endif; ! DEBUG
];

[ ConsultNounFilterToken obj n tf;
if (token_filter ofclass Routine) {
n = noun;
noun = obj;
tf = indirect(token_filter);
noun = n;
return tf;
}
if (obj has (token_filter-1)) rtrue;
rfalse;
];

-) instead of "Match List" in "Parser.i6t".


Changes are made above to the ConsultNounFilterToken routine which in its original form looks like this:
Code:
[ ConsultNounFilterToken obj;
if (token_filter ofclass Routine) {
noun = obj;
return indirect(token_filter);
}
if (obj has (token_filter-1)) rtrue;
rfalse;
];

_________________
Man ska inte tro allt man tänker.


Top
 Profile Send private message  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: gurok and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group