小例程

我有10个观察环境的传感器。 如果OK,传感器为1,否则为0。 我需要创建一个功能,如果至少有3个传感器位于0,并且警告消息仅显示一次,则会向终端输出警告消息。 这我需要在剪辑中完成。

谢谢。

   (deffacts listaSenzor
    (sensor L1 0)
    (sensor L2 0) 
    (sensor L3 1)
    (sensor L4 1)
    (sensor L5 1)
    (sensor L6 1)
    (sensor L7 0)
    (sensor L8 1)
    (sensor L9 0)
    )
    (defrule rr
        (sensor ?a  0 )
        (sensor ?b  0 )
        (sensor ?c  0 )
        =>
        printout t ?a ?b ?c "==>WARNING" crlf)
        )

有两个问题需要处理。 首先,您定义的模式可以多次匹配相同的事实(例如,传感器L1将绑定到abc )。 为了解决这个问题,你需要确保abc是唯一的。 其中一种方法如下(请注意,我还在printout语句前添加了一个缺失的“(”):

(deffacts listaSenzor
    (sensor L1 0)
    (sensor L2 0) 
    (sensor L3 1)
    (sensor L4 1)
    (sensor L5 1)
    (sensor L6 1)
    (sensor L7 0)
    (sensor L8 1)
    (sensor L9 0))
(defrule rr
    (sensor ?a 0)
    (sensor ?b 0)
    (sensor ?c 0)
    (test (neq ?a ?b))
    (test (neq ?a ?c))
    (test (neq ?b ?c))
=>
    (printout t ?a ?b ?c "==>WARNING" crlf))

针对你的事实运行这个规则给出:

CLIPS> (reset)
CLIPS> (run)
L9L7L2==>WARNING
L9L7L1==>WARNING
L9L2L7==>WARNING
...
L1L2L7==>WARNING
L2L1L7==>WARNING

此警告现在仅在有三个或更多不正常传感器时才会生成; 然而,输出提出了第二个问题,即您的警告正在多次生成(每个独特的三个非OK传感器的组合)。 为了解决这个问题,你可能需要一个控制的事实来防止规则被多次触发。 要达到此目的,您可以使用以下方法修改规则:

(defrule rr
    (not (sensor-warning))
    (sensor ?a 0)
    (sensor ?b 0)
    (sensor ?c 0)
    (test (neq ?a ?b))
    (test (neq ?a ?c))
    (test (neq ?b ?c))
=>
    (assert (sensor-warning))
    (printout t ?a ?b ?c "==>WARNING" crlf))

这可以确保规则只会触发一次(除非您收回sensor-warning事实)。 使用更新后的规则运行:

CLIPS> (reset)
CLIPS> (run)
L9L7L2==>WARNING
CLIPS> 

这是解决您的问题的简单方法。 如果您可能更改应触发规则的非OK传感器的数量,那么您应该使用更一般的逻辑来替换“硬连线”传感器名称比较(例如,您可以计算不合格传感器的总数以及将其与您的阈值进行比较)。


这是另一种方法:

(deftemplate sensor
   (slot id)
   (slot value))

(deffacts listaSenzor
   (sensor (id L1) (value 0))
   (sensor (id L2) (value 0)) 
   (sensor (id L3) (value 1))
   (sensor (id L4) (value 1))
   (sensor (id L5) (value 1))
   (sensor (id L6) (value 1))
   (sensor (id L7) (value 0))
   (sensor (id L8) (value 1))
   (sensor (id L9) (value 0)))

(defrule rr
   (exists 
      (sensor (id ?id1) (value 0))
      (sensor (id ?id2&~?id1) (value 0))
      (sensor (id ?id3&~?id2&~?id1) (value 0)))
   =>
   (bind ?sensors (create$))
   (do-for-all-facts ((?f sensor)) (eq ?f:value 0)
      (bind ?sensors (create$ ?sensors ?f:id)))
   (printout t (str-implode ?sensors) " ==> WARNING" crlf))

如果超过3个值为0,则会打印所有传感器。

CLIPS> (reset)
CLIPS> (run)
L1 L2 L7 L9 ==> WARNING
CLIPS> 
链接地址: http://www.djcxy.com/p/76183.html

上一篇: small routine program

下一篇: Loader: onLoadFinished called only once