在Rule中使用全局变量可能会带来些问题。如下,
(defglobal ?*GLOBAL* = "Old")
(deftemplate Item1 (slot value (type STRING)))
(deftemplate Item2 (slot value (type STRING)))
(defrule GlobalVariableIssue
(Item1 (value ?*GLOBAL*))
(Item2 (value ?*GLOBAL*))
=>
(printout t "Rule should not fire." crlf))
这里GlobalVariableIssue需要Item1、Item2的值都和全局变量?GLOBAL相同。理所当然Item1、Item2值必须得是相同的,不过总有预计之外的情况出现,
(assert (Item1 (value "Old")))
(bind ?*GLOBAL* "New")
(assert (Item2 (value "New")))
这里Item1、Item2的值最后是不同的,也就是说按照设想Rule是不会触发的。不过控制台上打出了,
Rule should not fire.
Item1、Item2的值分别和?GLOBAL相等过,而修改全局变量并不会对Jess的Rete网络产生影响,于是最终Rule的两个分支都得到了满足。可以看出,全局变量在LHS出现还是会有些风险。
为了满足上述的需求,Rule可以调整为,
(defrule GlobalVariableNoIssue
(Item1 (value ?value))
(Item2 (value ?value))
(test (eq ?value ?*GLOBAL*))
=>
(printout t "Rule will not fire." crlf))
当然如果全局变量只是作为全局共享的常量进行使用的话,那么在LHS引入就是不会有问题的。