写Rule的时候不加注意的话,比较容易写出死循环的代码来。
死循环有两种情况:
- 自循环,R1->R1。
- 链循环,R1->R2->R3->...->R1。
对于第一种情形,Jess提供了no-loop来避免一条Rule重复激活自身,在定义Rule的时候将no-loop设为TRUE即可,
(defrule NoLoop
(declare (no-loop TRUE))
=>
)
不过no-loop好像有不少关联的bug,因此并不算很好用。对于自循环的情形,更好的避免方法是在写Rule的时候就考虑是否会产生循环,因为只和当前的代码片段相关,并不难做到。
Jess还提供了slot-specific这一选项,当Template里面将slot-specific设为TRUE后,只有当相关slot出现在Rule的LHS并修改后才会触发Rule。如果不进行这一设置的话,对Fact的每一次修改都会导致相应的规则被触发(满足Rule的激活条件)。
在目前看来,那些不会被修改的Template无需设置slot-specific选项,而那些需要被修改的则最好全部设置slot-specific。 第二种情况并没有好的方法去避免,更多的只能依赖编码时候的周密考虑,以及测试代码的完备。