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

时间:2015-05-19 11:21:30

标签: 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))
) 

由于

1 个答案:

答案 0 :(得分: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?
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

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

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>