-1

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}
isabelle
  • 3
  • 3
  • 1
    Hi, I don't think that bounties are appropriate on SO. You can remove this line and add some detail. – creyD Jul 13 '19 at 13:11
  • Ok I removed the line, but I hope the issue is pretty self-explanatory. For example I have some data like: Apple = 3.5 Banana = 5 Apple = 4.5 desired output would be: {Banana=5}, {Apple=8} – isabelle Jul 13 '19 at 14:01
  • What you are searching for is a dictionary a custom add function which checks if there already is a value for the added key and if so it adds both of them up. – creyD Jul 13 '19 at 16:46
  • If a dict doesn't exist in the programming language you will need to create your own data structure for a similar usage. – creyD Jul 13 '19 at 16:48
  • If you mean [this as CLIPS](http://www.clipsrules.net) then there is no mention of the dictionary data type in [the documentation](http://www.clipsrules.net/Documentation.html). I could add example code on how to do this in Python or a similar language, but as you wrote you already know how to do it in other languages I don't think it would help you. – creyD Jul 13 '19 at 16:51
  • yes exactly, I already can figure it out in more "advanced" languages like Python, since it has dictioniaries. But I need it working in CLIPS :/ Thanks – isabelle Jul 14 '19 at 12:03

1 Answers1

0
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> 
Gary Riley
  • 10,130
  • 2
  • 19
  • 34
  • This works very well! Thank you very much. Your time is well appreciated. – isabelle Jul 22 '19 at 17:46
  • is it possible to use a for loop so that I could conveniently insert new data pairs? Instead of (send [d1] add item3 8) for example, I d like to send to [d1] every data pair I have stored in a certain multifield? Thank you – isabelle Jul 24 '19 at 16:47
  • Yes, if you assign the keys to a multifield variable and the values to another multifield variable, you could use something like (loop-for-count (?i 1 (length$ ?keys)) (println (nth$ ?i ?keys) "=" (nth$ ?i ?values))) where the println call would be replaced with a call to add each key/value to the DICTIONARY. – Gary Riley Jul 24 '19 at 18:25