在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引入就是不会有问题的。