Правило CLIPS не соответствует - PullRequest
1 голос
/ 29 мая 2020

У меня проблема с соответствием правил в 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 -ieces-col = 0 и проверка верна? Где я ошибаюсь?

1 Ответ

1 голос
/ 04 июня 2020

Это соответствующее описание поведения из CLIPS Basi c Руководство по программированию, раздел 5.4.2 Условный элемент тестирования:

Тестовый CE оценивается, когда все выполняющиеся CE удовлетворены. Это означает, что тестовый CE будет оцениваться более одного раза, если последующие CE могут быть удовлетворены более чем одной группой объектов шаблона. Чтобы вызвать переоценку тестового CE, необходимо изменить объект шаблона, соответствующий CE до тестового CE.

Когда утверждается факт k-per-col, тестовый CE будет оценен. Если это произойдет до того, как будут утверждены какие-либо или все факты a-ячейки, то вы не получите тех же результатов, как если бы вы сначала подтвердили все факты a-ячейки, а затем факт k-per-col.

Чтобы гарантировать предсказуемое поведение, выражения, оцениваемые тестом CE, должны всегда возвращать одно и то же значение для определенного c набора аргументов. В этом случае функции get-unknow-col и get-boat -ieces-col могут возвращать разные значения, даже если параметр? Col такой же, как и в предыдущем вызове.

Некоторые языки на основе правил предоставляют Условный элемент "collect", который позволяет легко подсчитать количество фактов, соответствующих шаблону, но, к сожалению, 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> 
...