clipsexpert-system

Understand (forall) conditional element in CLIPS


in CLIPS it was mentioned that

(defrule example
   (forall (a ?x) (b ?x) (c ?x))
   =>)

is equivalent to

(defrule example
   (not (and (a ?x)
             (not (and (b ?x) (c ?x)))))
   =>) 

I Couldn't understand the conversion, does it mean: we do not need the case where there is "a" but not followed by "b" that is not followed by "c" or ?

moreover for the following facts

 (deffacts students
    (person "a")
    (person "l")
    (student "a")
    (student "l")
    (student "f")
    (has-laptop "a")
    (has-laptop "l")
    (has-laptop "f")
    (part-time "a")
    (part-time "l")
    (part-time "f")
    )

and the following rule

(defrule example
(forall (person ?x) (student ?x) (has-laptop ?x) (part-time ?x))
=> (printout t "yes  " crlf))

the out put after (run) is "yes" even though that there no (person "f")

I am not sure that I understand (forall) well


Solution

  • There's not any nuance to how the forall behaves. It behaves in the same way that a similar boolean expression would. So if you have this boolean expression:

    not (A and (not (B and C)))
    

    and A is false, then the expression will evaluate to true. The same behavior applies to your rule; if there is no person, then the forall will be matched.

    Language, however, can be nuanced. If I ask whether all of today's orders have been processed, I would expect the answer to be either yes or no. If there are no orders, then the answer would still be yes, although someone might provide that additional information. "We have no order, so yes" is still "yes".

    If I ask someone whether all of their pets have been vaccinated and chipped, I would also expect the answer to be either yes or no, but I think it more likely that people with no pets, would provide that additional information, perhaps because the question somewhat implies that the person being asked has a least one pet.

    So if you use forall, but want there to be at least one fact matching the first pattern in the forall, you have to add an additional pattern to the rule:

    (defrule all-safe
       (exists (pet ?))
       (forall (pet ?pet)
               (vaccinated ?pet)
               (chipped ?pet))
       =>
       (println "All pets are vaccinated and chipped."))