我有10个监视环境的传感器。如果正常,则传感器为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
将绑定(bind)到a
,b
和c
)。要解决此问题,您需要确保a
,b
和c
是唯一的。执行此操作的一种方法如下(请注意,我还在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>
这是解决您的问题的简单方法。如果您可能会更改应触发规则的非正常传感器的数量,那么您可能应该用更通用的逻辑替换“硬连线”传感器名称比较(例如,您可以计算非正常传感器的总数和将其与您的阈值进行比较)。
关于clips - 剪辑-小型例行程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20609840/