Menu

CLIPS crash in FactJNGetVar3

Help
vranoch
2015-05-06
2015-07-10
  • vranoch

    vranoch - 2015-05-06

    Hi Gary,

    I found after some time another case which causes CLIPS to crash in the FactJNGetVar3 function. Tried it with the latest sources. Could You check it, please:

    rule:

    (defrule if 
        (and  
            (exists 
                (SAD T ?tx1 T01 ?t01)
                (SAD T ?tx1 T02 ?t02)
                (or  
                    (test (not (not (str-index  "ABCD" ?t01)))) 
                    (test (not (not (str-index  "ABCD" ?t02))))
                ) 
            ) 
            (exists 
                (SAD G ?gx1 G02N ?g02n)
                (and  
                    (test (eq (str-index  "9900" ?g02n) 1)) 
                    (exists 
                        (SAD T ?tx2 T08 ?t08)
                        (SAD G ?gx1 G01 ?g01)
                        (or  
                            (test (<= ?t08 0)) 
                            (test (= ?t08 ?g01))
                        )
                    )
                )
            )
        )
    =>
        (printout t "FOUND" crlf)
    )
    

    facts:

    (SAD G 2 G01 2)
    (SAD G 2 G02N "99009000")
    (SAD T 3 T01 "ABCD XYX")
    (SAD T 3 T02 "XYZ CDE")
    (SAD T 3 T08 2)
    

    Thanks Vranoch

     
  • Gary Riley

    Gary Riley - 2015-05-07

    I'll take a look.

     
  • Gary Riley

    Gary Riley - 2015-05-13

    Checked in a fix to the subversion repository

     
  • vranoch

    vranoch - 2015-05-13

    Thanks Gary, what was the problem?

     
  • Gary Riley

    Gary Riley - 2015-05-15

    During pattern matching variables are retrieved from partial matches. The index for retrieval was being computed incorrectly in some cases. Here's a simpler example that has the same issue:

    CLIPS> 
    (defrule if 
       (not (and (not (and (A) (B)))
                 (C)))
       (not (and (SAD ?v)
                 (SAD ?v)))
       =>)
    CLIPS> 
    (deffacts stuff
       (SAD 2))
    CLIPS> (reset)
       .
       .
       .
    Crash
    

    In this case, the comparison of the variable ?v from the SAD pattern was using an index that was 1 larger than it should have been.

     
  • vranoch

    vranoch - 2015-07-07

    Hi Gary,

    I found another occurrence of this problem:

    rule:

    ~~~~~~~~~~~~~~~~~~~~~~

    (defrule if ""
    (exists
    (or
    (exists
    (SAD H H04 ?h04)
    (SAD G ?ix_g G11 ?g11)
    (or
    (and
    (test (> (str-length ?h04) 0))
    (test (not (not (str-index ?h04 "IR,IN,SY,KP,TR,AE"))))
    )
    (and
    (test (> (str-length ?g11) 0))
    (test (not (not (str-index ?g11 "IR,IN,SY,KP,TR,AE"))))
    )
    )
    )
    (exists
    (SAD T ?ix_t T05 ?t05)
    (SAD T ?ix_t T05 ?t05)
    (and
    (test (> (str-length ?t05) 0))
    (test (not (not (str-index ?t05 "IR,IN,SY,KP,TR,AE"))))
    )
    )
    )
    )

    =>
    )

    facts:
    

    (SAD H H04 "SG")
    (SAD G 1 G11 "SG")
    (SAD T 1 T05 "BE")

    ~~~~~~~~~~~~~~~~~~~~~~~~

    Could You look at it, please?

    Thanks Vranoch

     
  • Gary Riley

    Gary Riley - 2015-07-08

    I'll take a look.

     
  • Gary Riley

    Gary Riley - 2015-07-10

    A fix has been checked into the SVN repository.

     
  • vranoch

    vranoch - 2015-07-10

    Thanks a lot Gary,

    What was the problem, what combinations of expressions were affected by this bug? What types may still be endangered?

    I temporarily worked-around the crash by joining duplicated facts in the LHS. Is it the substance of the problem? Can it have any performance consequences (speedup)?

    I have one more example that was causing a crash, do You also want to analýze it od shall I just try the fix?

    Thanks Vranoch

     
  • Gary Riley

    Gary Riley - 2015-07-10

    Go ahead and post the example. It's always good to have more than occurrence of a bug for regression testing even if the existing fix covers it.

    I used a different approach for building the rete network in earlier versions of 6.3, but then reverted to the method used by 6.24 in the final release. I missed a piece of code when rolling back changes. The simplest piece of code that I could derive from your original example that crashed was this:

    (deftemplate C (slot x))
    (deftemplate D (slot x))
    
    (defrule if ""
        (not (and (not (not (and (not (and (W) 
                                           (X)))
                                 (not (and (Y) 
                                           (Z))))))
                   (C (x ?ix_t))
                   (D (x ?ix_t))))
       =>)
    
    (assert (C (x 1)))
    

    You have to have several levels of nested not/exists containing multiple patterns and more than one grouping closed before the next pattern is encountered (such as after the Z pattern). Pattern indices for retrieving variables need to be computed correctly and normally for simple rules which do not contain multiple patterns within a not/exist, the index for the Nth pattern in the rule is N-1. In this example, the index for pattern C needs to be 1 and pattern D needs to be 2, but these were incorrectly computed as 2 and 3. The crash was caused by attempting to access an element beyond the valid length of an array. I wouldn't expect this to have performance consequences, but it's possible that there were cases where the wrong index was being used for retrieving a variable that didn't cause a crash and that this might have made a difference in the amount of computation that a rule had to do.

     

Log in to post a comment.