1

我对 Clips 中的规则匹配有疑问,特别是我无法理解为什么该规则不生效。

(deffunction get-unknow-col (?col)
    (bind ?facts (length (find-all-facts ((?a a-cell)) (and (eq ?a:y ?col) (eq ?a:content unk)))))
    (return ?facts)
)

(deffunction get-boat-pieces-col (?col)
    (bind ?facts (length (find-all-facts ((?a a-cell)) (and (eq ?a:y ?col) (and (neq ?a:content unk) (neq ?a:content water))))))
    (return ?facts)
)

(defrule mark-remaining-unk-cells-col (declare (salience 40))
    (k-per-col (col ?y) (num ?num))
    (test (= (+ (get-unknow-col ?y) (get-boat-pieces-col ?y)) ?num))
=>
    (do-for-all-facts ((?cell a-cell)) (and (eq ?cell:y ?y) (eq ?cell:content unk))
        (modify ?cell (content boat-piece))
    )
)

但是在(事实)中,我有正确的值,实际上是在运行:

(k-per-col (col 9) (num 1))

(get-unknow-col 9)
1
(get-boat-pieces-col 9)
0
CLIPS> (= (+ (get-unknow-col 9) (get-boat-pieces-col 9)) 1)
TRUE

该规则仅在 num 为 0(正确)时才有效:

FIRE   75 mark-remaining-unk-cells-col: f-137
***** Y:8 num: 0 get-unknown-col: 0 get-boat-pieces-col 0
FIRE   76 mark-remaining-unk-cells-col: f-136
***** Y:7 num: 0 get-unknown-col: 0 get-boat-pieces-col 0

为什么当 num=1, get-unknow-col=1, get-boat-pieces-col=0 并且测试为真时它不激活?我哪里错了?

4

1 回答 1

1

这是 CLIPS 基本编程指南第 5.4.2 节测试条件元素中的相关行为描述:

当满足所有进行中的 CE 时,评估测试 CE。这意味着如果不止一组模式实体可以满足进行中的 CE,则将多次评估测试 CE。为了引起测试CE的重新评估,必须改变与测试CE之前的CE匹配的模式实体。

当 k-per-col 事实被断言时,将评估测试 CE。如果这发生在任何或所有 a-cell 事实被断言之前,那么您将不会获得与首先断言所有 a-cell 事实然后是 k-per-col 事实相同的结果。

为了确保可预测的行为,测试 CE 评估的表达式应该始终为一组特定的参数返回相同的值。在这种情况下,get-unknow-col 和 get-boat-pieces-col 函数可以返回不同的值,即使参数 ?col 与之前的调用相同。

一些基于规则的语言提供了一个“收集”条件元素,可以轻松计算匹配模式的事实数量,但不幸的是 CLIPS 不提供此功能。为了添加此功能,您需要创建跟踪感兴趣值的事实和规则。

         CLIPS (6.31 6/12/19)
CLIPS> 
(deftemplate a-cell
   (slot id (default-dynamic (gensym*))) 
   (slot x)
   (slot y)
   (slot content (allowed-values water left right middle top bot sub unk)))
CLIPS> 
(deftemplate track-a-cell
   (slot x (default any))
   (slot y (default any))
   (slot content (default any))
   (multislot matches))
CLIPS>    
(deffacts trackers
   (track-a-cell (x any) (y 9) (content unk)))
CLIPS>    
(defrule add-a-cell-match
   (declare (salience 10))
   ?t <- (track-a-cell (x ?x1) (y ?y1) (content ?c1) (matches $?m))
   (a-cell (id ?id) (x ?x2) (y ?y2) (content ?c2))
   (test (and (not (member$ ?id ?m))
              (or (eq ?x1 any) (eq ?x1 ?x2))
              (or (eq ?y1 any) (eq ?y1 ?y2))
              (or (eq ?c1 any) (eq ?c1 ?c2))))
   =>
   (modify ?t (matches ?m ?id)))
CLIPS>    
(defrule remove-a-cell-match
   (declare (salience 10))
   ?t <- (track-a-cell (x ?x1) (y ?y1) (content ?c1) (matches $?b ?id $?e))
   (not (and (a-cell (id ?id) (x ?x2) (y ?y2) (content ?c2))
             (test (and (or (eq ?x1 any) (eq ?x1 ?x2))
                            (or (eq ?y1 any) (eq ?y1 ?y2))
                            (or (eq ?c1 any) (eq ?c1 ?c2))))))
   =>
   (modify ?t (matches ?b ?e)))
CLIPS> 
(deffacts init
   (a-cell (x 0) (y 9) (content water))
   (a-cell (x 1) (y 9) (content unk))
   (a-cell (x 2) (y 9) (content water))
   (a-cell (x 3) (y 9) (content water))
   (a-cell (x 5) (y 9) (content water))
   (a-cell (x 6) (y 9) (content unk))
   (a-cell (x 7) (y 9) (content water))
   (a-cell (x 8) (y 9) (content water))
   (a-cell (x 9) (y 9) (content water))
   (a-cell (x 4) (y 9) (content unk)))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-2     (a-cell (id gen1) (x 0) (y 9) (content water))
f-3     (a-cell (id gen2) (x 1) (y 9) (content unk))
f-4     (a-cell (id gen3) (x 2) (y 9) (content water))
f-5     (a-cell (id gen4) (x 3) (y 9) (content water))
f-6     (a-cell (id gen5) (x 5) (y 9) (content water))
f-7     (a-cell (id gen6) (x 6) (y 9) (content unk))
f-8     (a-cell (id gen7) (x 7) (y 9) (content water))
f-9     (a-cell (id gen8) (x 8) (y 9) (content water))
f-10    (a-cell (id gen9) (x 9) (y 9) (content water))
f-11    (a-cell (id gen10) (x 4) (y 9) (content unk))
f-14    (track-a-cell (x any) (y 9) (content unk) (matches gen10 gen6 gen2))
For a total of 12 facts.
CLIPS> (retract 3 7)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-2     (a-cell (id gen1) (x 0) (y 9) (content water))
f-4     (a-cell (id gen3) (x 2) (y 9) (content water))
f-5     (a-cell (id gen4) (x 3) (y 9) (content water))
f-6     (a-cell (id gen5) (x 5) (y 9) (content water))
f-8     (a-cell (id gen7) (x 7) (y 9) (content water))
f-9     (a-cell (id gen8) (x 8) (y 9) (content water))
f-10    (a-cell (id gen9) (x 9) (y 9) (content water))
f-11    (a-cell (id gen10) (x 4) (y 9) (content unk))
f-16    (track-a-cell (x any) (y 9) (content unk) (matches gen10))
For a total of 10 facts.
CLIPS> (assert (a-cell (x 1) (y 9) (content unk)))
<Fact-17>
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-2     (a-cell (id gen1) (x 0) (y 9) (content water))
f-4     (a-cell (id gen3) (x 2) (y 9) (content water))
f-5     (a-cell (id gen4) (x 3) (y 9) (content water))
f-6     (a-cell (id gen5) (x 5) (y 9) (content water))
f-8     (a-cell (id gen7) (x 7) (y 9) (content water))
f-9     (a-cell (id gen8) (x 8) (y 9) (content water))
f-10    (a-cell (id gen9) (x 9) (y 9) (content water))
f-11    (a-cell (id gen10) (x 4) (y 9) (content unk))
f-17    (a-cell (id gen11) (x 1) (y 9) (content unk))
f-18    (track-a-cell (x any) (y 9) (content unk) (matches gen10 gen11))
For a total of 11 facts.
CLIPS> 
于 2020-06-04T17:19:15.640 回答