CLIPS rule dont match

六月ゝ 毕业季﹏ 提交于 2020-08-09 09:16:52

问题


I have a problem with a rule match in Clips, in particular i can't understand why this rule doesn't actives.

(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))
    )
)

But in (facts) I have the correct values, in fact running:

(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

The rule instead works only if num is 0 (correctly):

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

Why it doesnt activate when num=1, get-unknow-col=1, get-boat-pieces-col=0 and the test is true? Where i'm wrong?


回答1:


This is the relevant behavior description from the CLIPS Basic Programming Guide, Section 5.4.2 Test Conditional Element:

A test CE is evaluated when all proceeding CEs are satisfied. This means that a test CE will be evaluated more than once if the proceeding CEs can be satisfied by more than one group of pattern entities. In order to cause the reevaluation of a test CE, a pattern entity matching a CE prior to the test CE must be changed.

When the k-per-col fact is asserted the test CE will be evaluated. If this occurs before any or all a-cell facts have been asserted, then you will not get the same results as if you had asserted all of the a-cell facts first and then the k-per-col fact.

In order to insure predictable behavior, expressions evaluated by the test CE should always return the same value for a specific set of arguments. In this case, the get-unknow-col and get-boat-pieces-col functions can return different values even if the parameter ?col is the same as a previous call.

Some rule-based language provide a "collect" conditional element which allows to easily count the number of facts matching a pattern, but unfortunately CLIPS does not provide this. In order to add this functionality, you'd need to create facts and rules which track the values of interest.

         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> 


来源:https://stackoverflow.com/questions/62075494/clips-rule-dont-match

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!