I am trying to find out the maximum element from a list, e.g.
(deffacts list
(list 1 2 3 4 5 6 7 6 5 4 3 2 1))
in CLIPS. How can I do that, in a very simple way, in a defrule?
Also, if I have a template for a patient, with the following slots :
(deftemplate patient
(slot name)
(slot age)
(multislot tens_max)
(multislot tens_min))
(deffacts data_patient
(patient (name John) (age 22) (tens_max 13 15 22 11) (tens_min 6 7 14 6))
)
and I want to find out the maximum element from the last multislot, tens_min, how can I do that?
I would appreciate any suggestion.
You can use the max function to find the maximum value of its arguments. You can bind the list of numbers to a multifield variable in the conditions of a rule. The max function however expects separate arguments so you can't just pass it a multifield value. You can use the expand$ function to split a multifield value into separate arguments for a function call. The max function expects at least 2 arguments in CLIPS 6.3 and at least 1 in CLIPS 6.4, so for completeness you would need to handle these cases. You can create a deffunction to handle these edge cases in your code.
CLIPS (6.31 6/12/19)
CLIPS>
(deffunction my-max ($?values)
(switch (length$ ?values)
(case 0 then (return))
(case 1 then (return (nth$ 1 ?values)))
(default (return (max (expand$ ?values))))))
CLIPS>
(deffacts list
(list 1 2 3 4 5 6 7 6 5 4 3 2 1))
CLIPS>
(defrule list-max
(list $?values)
=>
(printout t "list max = " (my-max ?values) crlf))
CLIPS>
(deftemplate patient
(slot name)
(slot age)
(multislot tens_max)
(multislot tens_min))
CLIPS>
(deffacts data_patient
(patient (name John) (age 22) (tens_max 13 15 22 11) (tens_min 6 7 14 6)))
CLIPS>
(defrule patient-max
(patient (tens_min $?values))
=>
(printout t "patient max = " (my-max ?values) crlf))
CLIPS> (reset)
CLIPS> (run)
patient max = 14
list max = 7
CLIPS>