Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CLIPS runtime crash

I wrote a program which asserts the facts in the LHS of this rule:

(defrule check-open-better (declare (salience 50))
  ?f1 <- (newnode (ident ?id) (gcost ?g) (fcost ?f) (father ?anc))

         (status (ident ?id) (subject ?subject) (data $?eqL))
  ?f2 <- (status (ident ?old) (subject ?subject) (data $?eqL))

  ?f3 <- (node (ident ?old) (gcost ?g-old) (open yes))

  (test
      (eq
          (implode$
              (find-all-facts ((?f status))
                  (and
                     (eq(str-compare ?f:ident ?id) 0)
                     (eq(str-compare ?f:subject ?subject) 0)
                     (eq(str-compare (implode$ ?f:data) (implode$ $?eqL)) 0)
                  )
              )
          )

          (implode$
              (find-all-facts ((?f status))
                  (and
                      (eq(str-compare ?f:ident ?old) 0)
                      (eq(str-compare ?f:subject ?subject) 0)
                      (eq(str-compare (implode$ ?f:data) (implode$ $?eqL)) 0)
                  )
              )
          )
      0)
  )

  (test (< ?g ?g-old))

  ?f4 <- (open-better ?a)

 =>

  (assert (node (ident ?id) (gcost ?g) (fcost ?f) (father ?anc) (open yes)))
  (assert (open-better (+ ?a 1)))
  (retract ?f1 ?f2 ?f3 ?f4)
  (pop-focus)
  (pop-focus))

node, newnode and status are defined as deftemplate.

When this rule is in the agenda, CLIPS crash like it was typed the (exit) command.

I'm sure it's not fault of the rules that assert facts that allow this rule to be added in the agenda. Does anyone know why?

like image 497
beppe95 Avatar asked Jan 03 '23 02:01

beppe95


1 Answers

If CLIPS is crashing, it's a bug in CLIPS. I tried reproducing the problem by filling in the missing pieces and running in CLIPS 6.3, 6.31, and 6.4, but was unable to get a crash.

(deftemplate newnode 
   (slot ident)
   (slot gcost (type INTEGER))
   (slot fcost)
   (slot father))

(deftemplate status
   (slot ident)
   (slot subject)
   (multislot data))

(deftemplate node
   (slot ident)
   (slot gcost (type INTEGER))
   (slot open))

(deffacts start
   (node (ident "1") (gcost 10) (open yes))
   (open-better 0)
   (newnode (ident "2"))
   (status (ident "1"))
   (status (ident "2")))

Generally, it's a bad idea to use the query functions from the conditions of a rule because 1) you can use pattern matching and 2) the query contained within a test CE will not be reevaluated unless there's some changes to prior patterns.

It's not clear what you're trying to do with the find-all-facts calls. First, there's cruft in there that you don't need. The str-compare and implode$ function calls are unnecessary and the third argument of 0 to eq will cause the test CE to always fail since the return values of the find-all-facts calls will never be 0.

  (test
      (eq
              (find-all-facts ((?f status))
                  (and
                     (eq ?f:ident ?id)
                     (eq ?f:subject ?subject)
                     (eq ?f:data $?eqL)
                  )
              )

              (find-all-facts ((?f status))
                  (and
                      (eq ?f:ident ?old)
                      (eq ?f:subject ?subject)
                      (eq ?f:data $?eqL)
                  )
              )
      )
  )

Both find-all-fact calls must return the same facts in order for the test CE to be satisfied. That can only be true if there are no status facts or the ?id and ?old variables have the same value.

like image 187
Gary Riley Avatar answered Jan 17 '23 02:01

Gary Riley