CLIPS 运行时崩溃

CLIPS runtime crash

我编写了一个程序,它断言了这条规则的 LHS 中的事实:

(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))

nodenewnodestatus 定义为 deftemplate。

当这条规则被列入议事日程时,CLIPS 崩溃就像输入 (exit) 命令一样。

我敢肯定,断言允许将此规则添加到议程中的事实并不是规则的错。有谁知道为什么?

试试这个,应该有用。 :)

(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 (< ?g ?g-old))

?f4 <- (open-better ?a)

=>

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

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

then
    (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))

如果 CLIPS 崩溃,那是 CLIPS 中的错误。我尝试通过在 CLIPS 6.3、6.31 和 6.4 中填写缺失的部分和 运行 来重现该问题,但无法崩溃。

(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")))

一般来说,从规则的条件中使用查询函数是个坏主意,因为 1) 您可以使用模式匹配和 2) test CE 中包含的查询除非对先前的模式进行一些更改,否则不会重新评估。

不清楚您尝试使用 find-all-facts 调用做什么。首先,里面有一些你不需要的东西。 str-compareimplode$ 函数调用是不必要的,0 到 eq 的第三个参数将导致 test CE 总是失败,因为 find-all-facts 调用的 return 值永远不会为 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)
                  )
              )
      )
  )

两个 find-all-fact 调用必须 return 相同的事实才能满足 test CE .只有当没有 status 事实或 ?id?old 变量有相同的值。