如何将全局变量与 Clips 中的字符串进行比较?

How to compare a global variable to a string in Clips?

在我的系统中,用户输入 Y 或 N 来回答简单的问题。我在每个问题之后调用此规则来增加计数器。我的代码存在一些一般性问题,但我看不到哪里

(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))
) 

谢谢

语法错误可以更正如下:

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> 

但是,这不会产生您期望的行为,因为 ?*symcount* 不会递增。全局变量的行为以及为什么你不应该以你正在尝试的方式使用它们已经在前面讨论过:

How exactly (refresh) works in the clips?

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

您不应使用全局变量来跟踪反应和症状,而应使用事实或实例。这是一种方法:

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>

还有一个:

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>