在 CLIPS 中检查多个事实

Check multiple facts in CLIPS

假设我有一些这样的事实(我不知道有多少):lamp x 已关闭。通过 defrule,我逐渐打开所有 lamps,所以每个事实都将是:lamp x 已打开。我如何检查每个 lamp 是否打开。我知道如果有三个 lamp 我可以写:

(defrule checkAllLamps
    (lamp 1 is on)
    (lamp 2 is on)
    (lamp 3 is on)
    =>
    (printout t "All lamps are on now")
)

但是对于 x lamps? 谢谢!

您可以为此使用事实集查询函数(Basic Programming Guide 的第 12.9.12 章)。

(deftemplate lamp 
  (slot id (type INTEGER)) 
  (slot state (type SYMBOL)))

(defrule all-lamps-are-on 
  (lamp (state on)) 
  (test (>= (length$ (find-all-facts ((?l lamp)) (eq ?l:state on))) 3)) 
  => 
  (printout t "All lamps are on" crlf))     

以下是检查是否所有 lamp 都已开启的方法。 checkAllLamps 规则将根本没有 lamp 的情况视为所有 lamp 都亮着,而 checkAllLampsAtLeastOne 规则要求至少有一个 lamp 亮着。

         CLIPS (6.31 2/3/18)
CLIPS> 
(defrule checkAllLamps
   (not (lamp ? is off))
   =>
   (printout t "All lamps are on now" crlf))
CLIPS> 
(defrule checkAllLampsAtLeastOne
   (exists (lamp ? is on))
   (not (lamp ? is off))
   =>
   (printout t "All lamps are on now" crlf))
CLIPS> (agenda)
0      checkAllLamps: *
For a total of 1 activation.
CLIPS> (assert (lamp 1 is on))
<Fact-1>
CLIPS> (agenda)
0      checkAllLampsAtLeastOne: *,*
0      checkAllLamps: *
For a total of 2 activations.
CLIPS> (assert (lamp 2 is off))
<Fact-2>
CLIPS> (agenda)
CLIPS> (retract 2)
CLIPS> (assert (lamp 2 is on))
<Fact-3>
CLIPS> (agenda)
0      checkAllLampsAtLeastOne: *,*
0      checkAllLamps: *
For a total of 2 activations.
CLIPS>