您需要处理两个问题。首先是您定义的模式可以多次匹配同一事实(例如,传感器L1
将绑定到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
现在仅当存在三个或更多不正常传感器时才会生成警告;但是,输出显示了第二个问题,即您的警告被多次生成(对于三个不正常传感器的每个唯一组合一次)。为了解决这个问题,您可能需要一个控制事实来防止规则多次触发。为此,您可以使用以下内容修改规则:
(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>
这是解决您问题的简单方法。如果您可能会更改应该触发规则的不正常传感器的数量,那么您可能应该用更通用的逻辑替换“硬连线”传感器名称比较(例如,您可以计算不正常传感器的总数和将其与您的阈值进行比较)。