Valeria Torella
Valeria Torella

Reputation: 11

Delete one of more equal values in multislot clips

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

Answers (1)

Gary Riley
Gary Riley

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

Related Questions