I have 10 sensor that watch an environment. The sensor is 1 if OK and 0 if not. I need to create a functional that will print out a Warning message to the terminal if there are at least 3 sensor that are on 0, and the message warning to be showed only once. This I need to do in clips.
Thank you.
(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)
)
There are two issues you need to deal with. The first is that the patterns you defined can match the same fact multiple times (e.g., sensor
L1
will be bound toa
,b
, andc
). To get around this, you need to ensure thata
,b
, andc
are unique. One way to do this is as follows (note that I also added a missing "(" in front of yourprintout
statement):Running this rule against your facts gives:
The warning is now only generated when there are three or more not-OK sensors; however, the output presents the second issue, which is that your warning is being generated multiple times (once for every unique combination of three not-OK sensors). To get around this, you probably want a control fact to prevent the rule from firing multiple times. To achieve this, you could modify the rule with the following:
This ensures that the rule will only fire once (unless you retract the
sensor-warning
fact). Running with the updated rule:This is a simple solution to your problem. If you are likely to change the number of not-OK sensors that should trigger the rule, then you should probably replace the "hardwired" sensor name comparisons with more general logic (e.g., you could compute the total number of not-OK sensors and compare that to your threshold).