2
votes

I need some help with a CLIPS question. This is the problem:

"Assume that a CLIPS database contains facts that are instantiations of the following template:

(deftemplate recommendation
     (slot name)
     (slot message)
     (slot rating)
)

Write CLIPS rule to print messages in descending order according to rating. Each message is to be printed along with its associated name and rating."

I know the sort rule when there is a list such as:

(deffacts testlist
        (list 1 4 2 3 5 8 7 6 9 0)
    ) 

(defrule sort

         ?f <- (list $?head ?a ?b&:(< ?b ?a) $?tail)
=>
    (retract ?f)

    (assert (list $?head ?b ?a $?tail))
)

But I am not sure when is it in the deftemplate format. Can someone help please?

2

2 Answers

1
votes

The CLIPS do-for-all-facts makes it easier to do something like this but, unfortunately, it is not available on many systems by default and requires recompiling CLIPS to make it available.

If you assert facts for all items that need to be printed, then you can use forall to determine the item with the greatest rating:

(defrule assert-unprinted "Asserts each item that needs to be printed."
  (print-sorted)
  (recommendation (name ?n))
  =>
  (assert (unprinted ?n)))

(defrule retract-print-sorted "Retract print-sorted after all items enumerated."
  (declare (salience -10))
  ?f <- (print-sorted)
  =>
  (retract ?f))

(defrule print-greatest "Prints the unprinted item with the greatest rating."
  (not (print-sorted))
  ?u <- (unprinted ?name)
  (recommendation (name ?name) (rating ?rating))
  (forall (and (unprinted ?n) (recommendation (name ?n) (rating ?r)))
          (test (<= ?r ?rating)))
  =>
  (retract ?u)
  (printout t ?name " has rating " ?rating "." crlf))

Here are some example facts:

(deffacts recommendations
  (recommendation (name chocolate) (rating 10.0))
  (recommendation (name vanilla) (rating 6.8))
  (recommendation (name strawberry) (rating 8.5)))

And they are printed in descending order like this:

CLIPS> (reset)
CLIPS> (assert (print-sorted))
<Fact-4>
CLIPS> (run)
chocolate has rating 10.0.
strawberry has rating 8.5.
vanilla has rating 6.8.
CLIPS> 
1
votes
CLIPS> 
(deftemplate recommendation
   (slot name)
   (slot message)
   (slot rating))
CLIPS>      
(deffacts recommendations
   (recommendation (name chocolate) (rating 10.0))
   (recommendation (name vanilla) (rating 6.8))
   (recommendation (name strawberry) (rating 8.5)))
CLIPS> 
(deffunction rating-sort (?f1 ?f2)
   (< (fact-slot-value ?f1 rating) (fact-slot-value ?f2 rating)))
CLIPS>    
(defrule print
   =>
   (bind ?facts (find-all-facts ((?f recommendation)) TRUE))
   (bind ?facts (sort rating-sort ?facts))
   (progn$ (?f ?facts)
      (printout t (fact-slot-value ?f name) " has rating " (fact-slot-value ?f rating) "." crlf)))
CLIPS> (reset)
CLIPS> (run)
chocolate has rating 10.0.
strawberry has rating 8.5.
vanilla has rating 6.8.
CLIPS>