Search code examples
rule-engineclips

How can I store a function, like < or >= as a value for evaluating it later, in CLIPS?


I'm new into CLIPS, and I'm forced to work strictly in heuristic (non procedural) paradigm. I'm trying to store a comparison function as a value in a similar way as I do in Python or in LISP, so I can modify the effect of a rule, as follows:

(assert (comp >=))

(defrule assert-greatest "Prints the unsorted item with the greatest rating."
  (comp ?c)
  ?u <- (unsorted ?name)
  ?r <- (cinema (name ?name) (rate ?rate))
  (forall (and (unsorted ?n)(cinema (name ?n) (rate ?r)))
          (test ((eval ?c) ?r ?rate))
          )
  =>
  (retract ?u)
  (modify ?rec (name ?name) (rating ?rating))
  )
                                                                                                  

I'm not sure to understand the meaning of 'eval' in CLIPS, and probably I'm misusing it, but there might be something like (eval f) in LISP.


Solution

  • Eval expects a string:

             CLIPS (6.31 6/12/19)
    CLIPS> (eval "3")
    3
    CLIPS> (eval "(>= 3 4)")
    FALSE
    CLIPS> (eval "(>= 4 3)")
    TRUE
    CLIPS>
    

    In your code, you would need to use the str-cat function to build a string to pass to eval:

    (eval (str-cat "(" ?v " " ?r " " ?rate ")"))
    

    The funcall function is better for what you're trying to do:

    CLIPS> (funcall >= 4 3)
    TRUE
    CLIPS> (funcall >= 3 4)
    FALSE
    CLIPS>
    

    In your code replace the eval call with this:

    (funcall ?v ?r ?rate)