Question

I've been banging my head against the wall on this for quite some time now, and found no reference of how to accomplish what I'm about to illustrate. Say I have a grid of cells each of which corresponds to the following template:

(deftemplate cell 
    (slot x)
    (slot y)
    (slot type (allowed-values urban rural lake hill gate border))
)

Now the type of cells in my grid is randomly generated with (assert (cell (x <x_coord>) (y <y_coord>) (type <some_type>)) statements and I want to define the following rule which inspects all cells in a 3x3 range, centered on the center cell, and takes an action according to the type of cell inspected:

(defrule inspect
    (cell (x ?xval) (y ?yval))
    ; ...
=>
    (loop-for-count (?i -1 1) do
        (loop-for-count (?j -1 1) do
            ; get "type" of cell @ coordinates (- ?x ?i ), (+ ?y ?j)
            ; do stuff according to type (i.e. assert other facts)
        )
    )
)

How would I go about looking up a fact given certain criteria (in this case, the coordinates of the cell) on the RHS of a CLIPS rule? I know how to do pattern-matching on the LHS, but I was curious to know if it's possible to do so on the RHS as well. Thanks in advance.

Was it helpful?

Solution

Use the fact set query functions (section 12.9.12 in the Basic Programming Guide):

CLIPS> 
(deftemplate cell 
   (slot x)
   (slot y)
   (slot type (allowed-values urban rural lake hill gate border)))
CLIPS> 
(deftemplate inspect
   (slot x)
   (slot y))
CLIPS> 
(deffacts example
   (inspect (x 3) (y 3))
   (cell (type urban) (x 1) (y 1))
   (cell (type rural) (x 2) (y 3))
   (cell (type lake) (x 4) (y 4))
   (cell (type border) (x 4) (y 4))
   (cell (type hill) (x 3) (y 5))
   (cell (type gate) (x 3) (y 3)))
CLIPS> 
(defrule inspect
   ; Changed to inspect so the example does
   ; not fire this rule for every cell
   (inspect (x ?xval) (y ?yval))  
   =>
   (do-for-all-facts ((?c cell))
                     (and (<= (- ?xval 1) ?c:x (+ ?xval 1))
                          (<= (- ?yval 1) ?c:y (+ ?yval 1)))
      (printout t ?c:type " " ?c:x " " ?c:y crlf)))
CLIPS> (reset)
CLIPS> (run)
rural 2 3
lake 4 4
border 4 4
gate 3 3
CLIPS>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top