Search code examples
maxclips

How can I find the ID of the variable that has the maximum value in CLIPS?


I tried to find the best student according to their exam marks. I took them from the user. I want CLIPS to give me the ID of the best student. For example, student1 mark 70, student2 mark 80 and student 3 mark 100. CLIPS should tell me "The best student is ... because his/her point is ..." I used global variables but I'm not sure if it's true because it doesn't work.

(defglobal ?*student1mark* = 0)
(defglobal ?*student2mark* = 0)
(defglobal ?*student3mark* = 0)

(defrule get-marks
=>
(printout t "What is the exam mark of student1?" crlf)
(bind ?*student1mark* (read))
(assert (stu1mark ?*student1mark*))
(printout t "What is the exam mark of student2?" crlf)
(bind ?*student2mark* (read))
(assert (stu2mark ?*student2mark*))
(printout t "What is the exam mark of student3?" crlf)
(bind ?*student3mark* (read))
(assert (stu3mark ?*student3mark*))
(build (str-cat
        "(deffacts students (student student1 " ?*student1mark* " student student2 " ?*student2mark* " student student3 " ?*student3mark* "))")))

(defrule whichstudent
(student ?ID = (max ?*student1mark*" ?*student2mark*" ?*student3mark*))
=>
(printout t "The best student is " ?ID crlf))

Solution

  • I would not use global variables. I would go with a template and facts. One solution with the help of a rule would be this:

             CLIPS (6.30 3/17/15)
    CLIPS> (deftemplate student
        (slot id (type INTEGER) (default ?NONE))
        (slot mark (type INTEGER) (default ?NONE))
    )
    CLIPS> (deffacts students
        (student (id 1) (mark 80))
        (student (id 2) (mark 79))
        (student (id 4) (mark 60))
        (student (id 3) (mark 90))
    )
    CLIPS> (defrule best-mark
        (compare-students)
        (student (id ?id) (mark ?mark))
        (not 
            (student (id ?) (mark ?nmark&:(> ?nmark ?mark)))
        )
    =>
        (printout t "The best student is student no. " ?id crlf)
    )
    CLIPS> (reset)
    CLIPS> (assert (compare-students))
    <Fact-5>
    CLIPS> (run)
    The best student is student no. 3
    

    The key part is

        (student (id ?id) (mark ?mark))
        (not 
            (student (id ?) (mark ?nmark&:(> ?nmark ?mark)))
        )
    

    So this rule matches with a student fact, if there is no other student with a higher mark.