Использование существует в операторе if - PullRequest
0 голосов
/ 29 марта 2019

Я пытаюсь реализовать игру жизни в CLIPS, и я столкнулся с проблемой (отсутствует объявление функции для 'exist') с оператором exist при попытке подсчитать соседей для каждой ячейки. Разве вы не можете использовать оператор существующие в операторе if? Как мне подойти к задаче подсчета соседей?

Это шаблон ячейки:

(deftemplate cell
    (slot iteration)
    (slot x)
    (slot y)
)

Это функция:

(deffunction countneighbors (?i ?j ?c)
    (bind ?*neighbors* 0)
    (if (exists (cell (iteration ?c) (x (- ?i 1)) (y (- ?j 1)))) then
        (bind ?*neighbors* (+ 0 1 ?*neighbors*))
    )
    (if (exists (cell (iteration ?c) (x (- ?i 1)) (y ?j))) then
        (bind ?*neighbors* (+ 0 1 ?*neighbors*))
    )
.
.
.
)

1 Ответ

1 голос
/ 29 марта 2019

Существующий условный элемент не является функцией, поэтому его нельзя вызывать как единое целое. Он может быть использован только в условиях правила. Вы можете использовать функции запроса фактов, если хотите перебрать группу фактов вне условий правила:

         CLIPS (6.31 2/3/18)
CLIPS> 
(deftemplate cell
   (slot iteration (default 0))
   (slot x)
   (slot y))
CLIPS> 
(deffacts cells
   (cell (x 1) (y 1))  
   (cell (x 1) (y 2))  ;;; - * *
   (cell (x 2) (y 3))  ;;; * - -
   (cell (x 3) (y 3))) ;;; * - -
CLIPS>    
(deffunction count-neighbors (?i ?j ?c)
   (bind ?neighbors 0)
   (do-for-all-facts ((?cell cell)) 
                     (and (= ?cell:iteration ?c)
                          (<= (abs (- ?i ?cell:x)) 1)
                          (<= (abs (- ?j ?cell:y)) 1)
                          (or (!= ?i ?cell:x) (!= ?j ?cell:y)))
      (bind ?neighbors (+ 1 ?neighbors)))
   ?neighbors)

CLIPS> (reset)
CLIPS> (count-neighbors 1 1 0)
1
CLIPS> (count-neighbors 2 2 0)
4
CLIPS> (count-neighbors 2 1 0)
2
CLIPS> 

Вот методика определения соседей по правилам:

CLIPS> (clear)
CLIPS> 
(deftemplate cell
   (slot iteration (default 0))
   (slot x)
   (slot y)
   (slot alive (default 0))
   (multislot neighbors))
CLIPS>    
(deftemplate direction
   (slot d)
   (slot dx)
   (slot dy))
CLIPS> 
(deffacts cells
   (cell (x 1) (y 1) (alive 1))  
   (cell (x 1) (y 2) (alive 1))
   (cell (x 1) (y 3))
   (cell (x 2) (y 1))
   (cell (x 2) (y 2))  
   (cell (x 2) (y 3) (alive 1))
   (cell (x 3) (y 1))
   (cell (x 3) (y 2))  
   (cell (x 3) (y 3) (alive 1)))
CLIPS> 
(deffacts directions
   (direction (d n)  (dx 0)  (dy 1))
   (direction (d ne) (dx 1)  (dy 1))
   (direction (d e)  (dx 1)  (dy 0))
   (direction (d se) (dx 1)  (dy -1))
   (direction (d s)  (dx 0)  (dy -1))
   (direction (d sw) (dx -1) (dy -1))
   (direction (d w)  (dx -1) (dy 0))
   (direction (d nw) (dx -1) (dy 1))) 
CLIPS>               
(defrule add-neighbor
   ?c <- (cell (x ?x) (y ?y) (neighbors $?n))
   (direction (d ?d) (dx ?dx) (dy ?dy))
   (cell (x =(+ ?x ?dx)) (y =(+ ?y ?dy)) (alive 1))
   (test (not (member$ ?d ?n)))
   =>
   (modify ?c (neighbors $?n ?d))) 
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-7     (cell (iteration 0) (x 3) (y 1) (alive 0) (neighbors))
f-10    (direction (d n) (dx 0) (dy 1))
f-11    (direction (d ne) (dx 1) (dy 1))
f-12    (direction (d e) (dx 1) (dy 0))
f-13    (direction (d se) (dx 1) (dy -1))
f-14    (direction (d s) (dx 0) (dy -1))
f-15    (direction (d sw) (dx -1) (dy -1))
f-16    (direction (d w) (dx -1) (dy 0))
f-17    (direction (d nw) (dx -1) (dy 1))
f-19    (cell (iteration 0) (x 2) (y 1) (alive 0) (neighbors nw w))
f-21    (cell (iteration 0) (x 3) (y 2) (alive 0) (neighbors nw n))
f-25    (cell (iteration 0) (x 2) (y 2) (alive 0) (neighbors w sw ne n))
f-26    (cell (iteration 0) (x 3) (y 3) (alive 1) (neighbors w))
f-28    (cell (iteration 0) (x 2) (y 3) (alive 1) (neighbors e sw))
f-30    (cell (iteration 0) (x 1) (y 2) (alive 1) (neighbors ne s))
f-31    (cell (iteration 0) (x 1) (y 1) (alive 1) (neighbors n))
f-33    (cell (iteration 0) (x 1) (y 3) (alive 0) (neighbors s e))
For a total of 18 facts.
CLIPS> 

Вот полная реализация, которая сохраняет только факты, представляющие живые ячейки.

(deffacts start-phase
   (phase neighbors))

(deftemplate cell
   (slot x)
   (slot y)
   (slot alive (default no))
   (multislot neighbors))

(deffacts glider
   (cell (x 1) (y 2) (alive yes))
   (cell (x 2) (y 3) (alive yes))
   (cell (x 3) (y 1) (alive yes))
   (cell (x 3) (y 2) (alive yes))
   (cell (x 3) (y 3) (alive yes)))

(deftemplate direction
   (slot tag)
   (slot dx (default 0))
   (slot dy (default 0)))

(deffacts directions
   (direction (tag n) (dy 1))
   (direction (tag ne) (dx 1) (dy 1))
   (direction (tag e) (dx 1))
   (direction (tag se) (dx 1) (dy -1))
   (direction (tag s) (dy -1))
   (direction (tag sw) (dx -1) (dy -1))
   (direction (tag w) (dx -1))
   (direction (tag nw) (dx -1) (dy 1)))

(defrule check-for-life
   (phase neighbors)
   (cell (x ?x) (y ?y) (alive yes))
   (direction (tag ?tag) (dx ?dx) (dy ?dy))
   (not (cell (x =(+ ?x ?dx)) (y =(+ ?y ?dy))))
   =>
   (assert (cell (x (+ ?x ?dx)) (y (+ ?y ?dy)))))

(defrule add-neighbor
   (phase neighbors)
   ?c <- (cell (x ?x) (y ?y) (neighbors $?n))
   (direction (tag ?t) (dx ?dx) (dy ?dy))
   (cell (x =(+ ?x ?dx)) (y =(+ ?y ?dy)) (alive yes))
   (test (not (member$ ?t ?n)))
   =>
   (modify ?c (neighbors ?t ?n)))

(defrule remove-neighbor
   (phase neighbors)
   ?c <- (cell (x ?x) (y ?y) (neighbors $?b ?t $?e))
   (direction (tag ?t) (dx ?dx) (dy ?dy))
   (not (cell (x =(+ ?x ?dx)) (y =(+ ?y ?dy)) (alive yes)))
   =>
   (modify ?c (neighbors ?b ?e)))

(defrule life-to-death
   (phase life)
   ?c <- (cell (alive yes) (neighbors $?n))
   (test (not (= (length$ ?n) 2)))
   (test (not (= (length$ ?n) 3)))
   =>
   (retract ?c)) 

(defrule death-to-life
   (phase life)
   ?c <- (cell (alive no) (neighbors $?n))
   (test (= (length$ ?n) 3))
   =>
   (modify ?c (alive yes))) 

(defrule death-to-death
   (phase life)
   ?c <- (cell (alive no) (neighbors $?n))
   (test (!= (length$ ?n) 3))
   =>
   (retract ?c)) 

(defrule neighbors-to-life
   (declare (salience -10))
   ?p <- (phase neighbors)
   =>
   (retract ?p)
   (assert (phase life)))

(defrule life-to-neighbors
   (declare (salience -10))
   ?p <- (phase life)
   =>
   (retract ?p)
   (assert (phase neighbors)))
...