Reputation: 11367
I'd like to retrieve a multislot containing object, and filter on a specific slot at the same time (fetching time). This is a code example:
(defclass OBJECT (is-a USER)
(slot uuid
(type STRING))
(slot enable
(type NUMBER)
(allowed-integers 0 1) (default 0)))
(defclass GROUP (is-a USER)
(slot uuid
(type STRING))
(multislot objects
(type INSTANCE)))
(defrule my-rule
?group <- (object (is-a GROUP) (uuid ?uuid) (objects $?objects&:(eq enable 1))) ;; I want only enable rooms
=>
(printout t "done" crlf))
Is it possible in CLIPS?
Thank you Nicola
Upvotes: 0
Views: 78
Reputation: 10757
You can filter the objects on the RHS of the rule:
CLIPS>
(defclass OBJ
(is-a USER)
(slot uuid
(type STRING))
(slot enable
(type NUMBER)
(allowed-integers 0 1)
(default 0)))
CLIPS>
(defclass GROUP (is-a USER)
(slot uuid
(type STRING))
(multislot objects
(type INSTANCE-NAME)))
CLIPS>
(definstances initial
([o1] of OBJ (enable 1))
([o2] of OBJ (enable 0))
([o3] of OBJ (enable 1))
([o4] of OBJ (enable 0))
([g1] of GROUP (objects [o1] [o2] [o3] [o4])))
CLIPS>
(deffunction filter (?objects ?slot ?value)
(bind ?result (create$))
(progn$ (?o ?objects)
(if (eq (send ?o (sym-cat get- ?slot)) ?value)
then
(bind ?result (create$ ?result ?o))))
?result)
CLIPS>
(defrule my-rule
?group <- (object (is-a GROUP)
(uuid ?uuid)
(objects $?objects))
=>
(bind ?objects (filter ?objects enable 1))
(printout t "Objects = " ?objects crlf))
CLIPS> (reset)
CLIPS> (run)
Objects = ([o1] [o3])
CLIPS>
Upvotes: 2