CLIPS运行时崩溃

时间:2018-07-20 13:43:42

标签: clips expert-system

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

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

2 个答案:

答案 0 :(得分:5)

如果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中包含的查询以前的模式有所变化。

目前尚不清楚您要使用查找全部事实调用做什么。首先,这里有您不需要的东西。不需要 str-compare implode $ 函数调用,并且0到 eq 的第三个参数将导致 test 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)
                  )
              )
      )
  )

所有事实调用都必须返回相同的事实,以便满足 test CE。只有在没有状态事实或?id ?旧变量具有相同值的情况下,这才是正确的。

答案 1 :(得分:2)

尝试这个,它应该可以工作。 :)

(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))
相关问题