Search code examples
clips

CLIPS. How can I check if a list of facts matching facts already given?


I need to create a rule that will check if the list of facts I have entered matches the facts already given. Then the fact / facts corresponding to at least one of the entered ones are displayed.

this is what I have:

(deftemplate rule (multislot problem) (slot cause))
(deffacts info
(rule (problem one) (cause one1))
(rule (problem two) (cause two2))
(rule (problem three) (cause three3))
 
 (defrule reading-input
 =>
 (printout t "Enter your problems: " )
 (assert (problem (read))))

 (defrule checking-input
 (problem $?problem)
 (rule (problem $?problem1) (cause ?cause1))
 (test (eq ?problem ?problem1))
  =>
 (printout t "cause: " ?cause1 crlf))

how this should work:

CLIPS> Enter your problems: one two
CLIPS> cause: one1
       cause: two2

Solution

  • Using the read function will retrieve just one value from your input. You need to use the readline function in conjunction with the explode$ function:

             CLIPS (6.4 2/9/21)
    CLIPS> (assert (problem (read)))
    one two
    <Fact-1>
    CLIPS> (assert (problem (readline)))
    one two
    <Fact-2>
    CLIPS> (assert (problem (explode$ (readline))))
    one two
    <Fact-3>
    CLIPS> (facts)
    f-1     (problem one)
    f-2     (problem "one two")
    f-3     (problem one two)
    For a total of 3 facts.
    CLIPS>
    

    You can then use multifield wildcards to isolate individual problems within your rule:

    CLIPS> (clear)
    CLIPS> 
    (deftemplate rule
       (multislot problem)
       (slot cause))
    CLIPS> 
    (deffacts info
       (rule (problem one) (cause one1))
       (rule (problem two four) (cause two2))
       (rule (problem one three five) (cause three3)))
    CLIPS>  
    (defrule reading-input
       =>
       (printout t "Enter your problems: " )
       (assert (problem (explode$ (readline)))))
    CLIPS> 
    (defrule checking-input
       (problem $? ?problem $?)
       (rule (problem $? ?problem $?) (cause ?cause))
       =>
       (printout t "Problem: " ?problem " cause: " ?cause crlf))
    CLIPS> (reset)
    CLIPS> (run)
    Enter your problems: one two
    Problem: one cause: three3
    Problem: one cause: one1
    Problem: two cause: two2
    CLIPS>