Search code examples
for-loopclipscounting-sort

Having list with values. If item exists several times, add value?


I want to get started with CLIPS, trying to realize a very simple task:

Item1 = 5
Item2 = 7
Item3 = 8
Item1 = 10

Lets say I have the variables or assignments above. Now I want a script to order the Items that have the min value to the max value. Additionally, Items with the same name (Item 1) should have their values summed up.

Already realized this in other languages, but I m totally lost in CLIPS.

NewList= {Item2=7,Item3=8,Item1=15}

Solution

  • CLIPS> 
    (defclass ENTRY
       (is-a USER)
       (slot key)
       (slot value))
    CLIPS>    
    (defclass DICTIONARY
       (is-a USER)
       (multislot entries))
    CLIPS> 
    (defmessage-handler DICTIONARY find-key-position (?key)
       (bind ?index 1)
       (foreach ?e ?self:entries
          (if (eq (send ?e get-key) ?key)
             then
             (return ?index))
          (bind ?index (+ ?index 1)))
       (return FALSE))
    CLIPS> 
    (defmessage-handler DICTIONARY add (?key ?value)
       (bind ?position 
          (send ?self find-key-position ?key))
       (if ?position
          then
          (bind ?entry (nth$ ?position ?self:entries))
          (send ?entry put-value (+ (send ?entry get-value) ?value))
          else
          (bind ?position (+ (length$ ?self:entries) 1))
          (bind ?entry
             (make-instance of ENTRY (key ?key) (value ?value)))
          (slot-direct-insert$ entries ?position ?entry)))
    CLIPS>    
    (defmessage-handler DICTIONARY display ()
       (printout t "{")
       (foreach ?e ?self:entries
          (printout t " " (send ?e get-key) "=" (send ?e get-value)))
       (printout t " }" crlf))
    CLIPS>    
    (deffunction sort-by-value (?e1 ?e2)
       (> (send ?e1 get-value) (send ?e2 get-value)))
    CLIPS>    
    (defmessage-handler DICTIONARY sort ()
       (bind ?self:entries (sort sort-by-value ?self:entries))
       TRUE)
    CLIPS> (make-instance d1 of DICTIONARY)
    [d1]
    CLIPS> (send [d1] display)
    { }
    CLIPS> (send [d1] add item1 5)
    TRUE
    CLIPS> (send [d1] add item2 7)
    TRUE
    CLIPS> (send [d1] add item3 8)
    TRUE
    CLIPS> (send [d1] display)
    { item1=5 item2=7 item3=8 }
    CLIPS> (send [d1] add item1 10)
    15
    CLIPS> (send [d1] display)
    { item1=15 item2=7 item3=8 }
    CLIPS> (send [d1] sort)
    TRUE
    CLIPS> (send [d1] display)
    { item2=7 item3=8 item1=15 }
    CLIPS>