Reputation: 11
I'm working in CLIPS, ad I have this deftemplate:
(deftemplate K-agent (multislot content) (slot free) (slot waste)
A possible K-agent fact could be:
(K-agent (content normal normal) (free 0) (waste no))
I want to apply this rule:
?k <- (K-agent (content $?cont) (free ?f))
=> (modify ?k (content (delete-member$ $?cont normal)) (free =(+ ?f 1)))
and to obtain this:
(K-agent (content normal) (free 1) (waste no))
but instead this is the effect of my rule:
(K-agent (content) (free 1) (waste no))
Is there any way to remove only one of the same values in a multislot? Thank you
Upvotes: 1
Views: 948
Reputation: 10757
Here's one way:
CLIPS> (clear)
CLIPS>
(deftemplate K-agent
(multislot content)
(slot free)
(slot waste))
CLIPS>
(deffacts start
(K-agent (content normal normal) (free 0) (waste no)))
CLIPS>
(defrule example
?k <- (K-agent (content $?begin normal $?end) (free ?f))
(test (or (member$ normal ?begin)
(member$ normal ?end)))
=>
(modify ?k (content (delete-member$ ?begin normal)
normal
(delete-member$ ?end normal))
(free =(+ ?f 1))))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-2 (K-agent (content normal) (free 1) (waste no))
For a total of 2 facts.
CLIPS>
And another:
CLIPS> (undefrule example)
CLIPS>
(deffunction count$ (?list ?value)
(bind ?count 0)
(foreach ?l ?list
(if (eq ?l ?value)
then
(bind ?count (+ ?count 1))))
(return ?count))
CLIPS>
(deffunction delete-duplicates$ (?list ?value)
(bind ?count (count$ ?list ?value))
(if (<= ?count 1)
then
(return ?list))
(loop-for-count (- ?count 1)
(bind ?pos (member$ ?value ?list))
(bind ?list (delete$ ?list ?pos ?pos)))
(return ?list))
CLIPS>
(defrule example
?k <- (K-agent (content $?cont) (free ?f))
(test (> (count$ ?cont normal) 1))
=>
(modify ?k (content (delete-duplicates$ ?cont normal))
(free =(+ ?f 1))))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-2 (K-agent (content normal) (free 1) (waste no))
For a total of 2 facts.
CLIPS>
Upvotes: 1