How to compare a global variable to a string in Cl

2019-08-08 02:21发布

问题:

In my system the user inputs a Y or N to answer simple questions. I call this rule after every question to increment a counter. There are some general problems with my code but i can't see where

(defrule QPain
         (initial-fact)
         =>
         (printout t "Are You In Pain? " crlf) 
         (bind ?*Answer* (read)) 
)
(defrule IncSym
     (test(=(str-compare (?*Answer*) "y")0))
      =>
     (bind ?*symcount* (+ ?*symcount* 1))
) 

Thanks

回答1:

The syntactic errors can be corrected as follows:

CLIPS> (clear)
CLIPS> (defglobal ?*Answer* = nil)
CLIPS> (defglobal ?*symcount* = 0)
CLIPS> 
(defrule QPain
   =>
   (printout t "Are you in pain? ") 
   (bind ?*Answer* (read)))
CLIPS>    
(defrule IncSym
   (test (eq ?*Answer* y))
   =>
   (bind ?*symcount* (+ ?*symcount* 1))) 
CLIPS> (reset)
CLIPS> (run)
Are you in pain? y
CLIPS> (show-defglobals)
?*Answer* = y
?*symcount* = 0
CLIPS> 

This won't produce the behavior you're expecting, however, since ?*symcount* will not be incremented. The behavior of global variables and why you should not be using them in the manner you're attempting has been discussed previously:

How exactly (refresh) works in the clips?
CLIPS: forcing a rule to re-evaluate the value of a global variable?
Number equality test fails in CLIPS pattern matching?
CLIPS constant compiler directive
How can I run the clips with out reset the fact when using CLIPS

Instead of using global variables to track responses and symptoms, you should use facts or instances. Here's one approach:

CLIPS> (clear)
CLIPS> 
(deftemplate symptom
   (slot id)
   (slot response))
CLIPS> 
(deftemplate symptom-list
   (multislot values))
CLIPS> 
(deffacts initial
   (symptom-list))
CLIPS>    
(defrule QPain
   =>
   (printout t "Are you in pain? ")
   (assert (symptom (id in-pain) (response (read)))))
CLIPS>   
(defrule IncSym
   (symptom (id ?id) (response y))
   ?f <- (symptom-list (values $?list))
   (test (not (member$ ?id ?list)))
   =>
   (modify ?f (values ?list ?id)))
CLIPS>    
(defrule symptoms-found
   (declare (salience -10))
   (symptom-list (values $?list))
   =>
   (printout t "Symptom count: " (length$ ?list) crlf))
CLIPS> (reset)
CLIPS> (run)
Are you in pain? y
Symptom count: 1
CLIPS> (reset)
CLIPS> (run)
Are you in pain? n
Symptom count: 0
CLIPS>

And another:

CLIPS> (clear)
CLIPS> 
(deftemplate symptom
   (slot id)
   (slot response))
CLIPS>    
(defrule QPain
   =>
   (printout t "Are you in pain? ")
   (assert (symptom (id in-pain) (response (read)))))
CLIPS>   
(defrule symptoms-found
   (declare (salience -10))
   =>
   (bind ?count (find-all-facts ((?f symptom)) (eq ?f:response y)))
   (printout t "Symptom count: " (length$ ?count) crlf))
CLIPS> (reset)
CLIPS> (run)
Are you in pain? y
Symptom count: 1
CLIPS> (reset)
CLIPS> (run)
Are you in pain? n
Symptom count: 0
CLIPS> 


标签: clips