Search code examples
clipsexpert-system

CLIPS accessing a property of a property


I read in this SO answer that it is

better to explicitly retrieve the slot value by matching it rather than using the slot accessor as this will cause the condition to be reevaluated whenever the slot value changes

What if I want to access the property of a property? For example,

given two instances a and b of classes A and B, respectively.

a has a property called ref_to_b which is a reference to b. b has a property called some_prop_of_b.

How do I match the following:

a with ref_to_b equal to b and some_prop_of_b equal to "some_string".

I tried this but got an error:

(defrule my_rule "comment me"
    (object (is-a A)
        (ref_to_b ?ref_to_b))
    (?ref_to_b
        (some_prop_of_b "some_string"))
=>
)

Solution

  • Place the instance name of the referenced instance in the ref_to_b slot and then use the name slot to match the reference:

    CLIPS> 
    (defclass A (is-a USER) (slot ref_to_b))
    CLIPS> 
    (defclass B (is-a USER) (slot some_prop_of_b))
    CLIPS> 
    (make-instance [b1] of B (some_prop_of_b "some_string"))
    [b1]
    CLIPS> 
    (make-instance [b2] of B (some_prop_of_b "not_some_string"))
    [b2]
    CLIPS> 
    (make-instance [a] of A (ref_to_b [b2]))
    [a]
    CLIPS> 
    (defrule my_rule
       (object (is-a A) (ref_to_b ?name_b))
       (object (name ?name_b) (some_prop_of_b "some_string"))
       =>)
    CLIPS> (agenda)
    CLIPS> (send [a] put-ref_to_b [b1])
    [b1]
    CLIPS> (agenda)
    0      my_rule: [a],[b1]
    For a total of 1 activation.
    CLIPS>