我编写了一个程序,该程序断言了该规则在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)命令一样。

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

最佳答案

如果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)除非对先前的模式进行一些更改,否则不会重新评估测试CE中包含的查询。

目前尚不清楚您要使用“查找所有事实”调用做什么。首先,这里有您不需要的东西。不需要str-compare和implode $函数调用,并且eq的第三个参数0会导致测试CE始终失败,因为find-all-facts调用的返回值永远不会为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)
                  )
              )
      )
  )


为了使测试CE得以满足,两个“所有事实查找”调用都必须返回相同的事实。仅当没有状态事实或?id和?old变量具有相同的值时,这才是正确的。

09-17 12:52