Search code examples
clips

Using bound pattern variables from an OR group to test conditional elements in CLIPS rules


I would essentially like to create 1 rule that will fire if either of 2 facts are above a certain value, i.e. a rule with the following LHS:

(or
    (object-0 (value ?x))
    (object-1 (value ?y))
)

(test
    (or
        (> ?x 1)
        (> ?y 2)
    )
)

The problem is that this won't work if one of those objects doesn't exist. This makes perfect sense because you can't operate on a variable that doesn't even exist.

I would really like to avoid splitting this into 2 separate rules, except as a last resort. Is there any way of doing this? Perhaps with some hacky (exist) statements?


Solution

  •          CLIPS (6.31 6/12/19)
    CLIPS> 
    (deftemplate object-0 
       (slot value))
    CLIPS>    
    (deftemplate object-1 
       (slot value))
    CLIPS> 
    (defrule example-1
       (or (object-0 (value ?x&:(> ?x 1)))
           (object-1 (value ?y&:(> ?y 2))))
       =>)
    CLIPS> 
    (defrule example-2
       (or (and (object-0 (value ?x))
                (test (> ?x 1)))
           (and (object-1 (value ?y))
                (test (> ?y 2))))
       =>)
    CLIPS> 
    (defrule example-3
       (exists (or (object-0 (value ?x&:(> ?x 1)))
                   (object-1 (value ?y&:(> ?y 2)))))
       =>)
    CLIPS> (assert (object-0 (value 3)) (object-1 (value 4)))
    <Fact-2>
    CLIPS> (agenda)
    0      example-1: f-2
    0      example-2: f-2
    0      example-1: f-1
    0      example-3: *
    0      example-2: f-1
    For a total of 5 activations.
    CLIPS>