Reputation: 3221
A person can own several cars but a car is owned by exactly one person. In clips
(defclass PERSON
(is-a USER)
(role concrete)
(pattern-match reactive)
(multislot cars) ; each list element should be a reference to an instance of type CAR
)
(defclass CAR
(is-a USER)
(role concrete)
(pattern-match reactive)
(slot owner) ; should be a reference to an instance of type PERSON
)
I am using pyclips. Now I would like to link an existing instance of CAR to an existing PERSON instance. My try:
clips_person_instance = clips.FindInstance(name_of_existing_person)
clips_car_instance = clips.FindInstance(name_of_existing_car)
list_of_cars = clips_person_instance.Slots["cars"]
list_of_cars.append(clips_car_instance)
clips_person_instance.Slots["cars"] = list_of_cars
This gives me
TypeError: list element of type
<class 'clips._clips_wrap.Instance'>
cannot be converted
As far as I can see it is a problem make pyclips add a list of instances to a slot. If it is just a single instance (no list), this works fine:
clips_car_instance.Slots["owner"] = clips_person_instance
My question: How do I "link" to class instances in (py)clips? In OO-words: How to I create an association between two objects? How do I create a "1 to many" relation in (py)clips?
Upvotes: 0
Views: 282
Reputation: 10757
It looks like fact and instance addresses are not fully supported in the python code to the same extent as the other CLIPS primitive data types. I'd suggest storing the instance name rather than the instance address in the multifield value (in this case, use clips_car_instance.Name rather than clips_car_instance). You'll have to use FindInstance to convert the instance name back to an instance address to manipulate the instance.
>>> import clips
>>> clips.Load("classes.clp")
>>> clips.Eval("(make-instance Fred of PERSON)")
<InstanceName 'Fred'>
>>> clips.Eval("(make-instance Toyota of CAR)")
<InstanceName 'Toyota'>
>>> name_of_existing_person = "Fred"
>>> name_of_existing_car = "Toyota"
>>> clips_person_instance = clips.FindInstance(name_of_existing_person)
>>> clips_car_instance = clips.FindInstance(name_of_existing_car)
>>> list_of_cars = clips_person_instance.Slots["cars"]
>>> list_of_cars.append(clips_car_instance.Name)
>>> clips_person_instance.Slots["cars"] = list_of_cars
>>> clips_person_instance.Slots["cars"]
<Multifield [<InstanceName 'Toyota'>]>
>>>
Upvotes: 1