There are two questions you need to deal with. Firstly, the patterns that you defined may coincide with the same fact several times (for example, the L1 sensor will be attached to a , b and c ). To get around this, you need to make sure that a , b and c unique. One way to do this is as follows (note that I also added the missing "(" before your 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))
Fulfilling this rule against your facts gives:
CLIPS> (reset) CLIPS> (run) L9L7L2==>WARNING L9L7L1==>WARNING L9L2L7==>WARNING ... L1L2L7==>WARNING L2L1L7==>WARNING
A warning is now generated only if there are three or more non-OK sensors; however, the output is the second problem, which is that your warning is generated several times (once for each unique combination of three non-OK sensors). To get around this, you probably want a telltale fact to stop the rule from firing several times. To do this, you can change the rule as follows:
(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))
This ensures that the rule will fire only once (unless you cancel the fact of sensor-warning ). Run with updated rule:
CLIPS> (reset) CLIPS> (run) L9L7L2==>WARNING CLIPS>
This is a simple solution to your problem. If you are likely to change the number of non-OK sensors that the rule should trigger, then you should probably replace the “mapped” sensor names with more general logic (for example, you could calculate the total number of non-OK sensors and compare this with your doorstep).
bogatron
source share