我已经为这个问题绞尽脑汁了很长时间,但没有找到任何参考资料来实现我接下来要说明的内容。假设我有一个由单元格组成的网格,每个单元格对应以下模板:
(deftemplate cell (slot x) (slot y) (slot type (allowed-values urban rural lake hill gate border)))
现在,我的网格中单元格的类型是通过(assert (cell (x <x_coord>) (y <y_coord>) (type <some_type>))
语句随机生成的。我想定义以下规则,该规则检查以中心单元格为中心的3×3范围内的所有单元格,并根据所检查单元格的类型采取行动:
(defrule inspect (cell (x ?xval) (y ?yval)) ; ...=> (loop-for-count (?i -1 1) do (loop-for-count (?j -1 1) do ; 获取坐标 (- ?x ?i ), (+ ?y ?j) 处的单元格的 "type" ; 根据类型执行操作(例如,断言其他事实) ) ))
在 CLIPS 规则的 RHS 中,如何根据某些条件(在本例中是单元格的坐标)查找事实?我知道如何在 LHS 上进行模式匹配,但我很好奇是否也可以在 RHS 上这样做。提前感谢。
回答:
使用事实集查询函数(基础编程指南中的第12.9.12节):
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 ; 更改为 inspect 以便示例不会 ; 为每个单元格触发此规则 (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 3lake 4 4border 4 4gate 3 3CLIPS>