CLIPS运行时崩溃

bep*_*e95 4 expert-system clips

我写了一个程序,断言本规则的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))
Run Code Online (Sandbox Code Playgroud)

node,newnode并被status定义为deftemplate.

当这个规则在议程中时,CLIPS会像输入(exit)命令一样崩溃.

我敢肯定,这些规则的主张不允许将此规则添加到议程中,这不是错误.有谁知道为什么?

Gar*_*ley 6

如果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")))
Run Code Online (Sandbox Code Playgroud)

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

目前还不清楚你在尝试使用find-all-facts调用.首先,那里有你不需要的东西.该STR-比较内爆$函数调用是不必要的,0到第三个参数均衡器会导致测试 CE总是失败,因为返回值的发现,所有的事实通话将永远为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)
                  )
              )
      )
  )
Run Code Online (Sandbox Code Playgroud)

两个find-all-fact调用必须返回相同的事实才能满足测试 CE.只有在没有状态事实或者?id变量具有相同值时才能成立.