剪辑如何不重复规则执行?

How does clips not repeat rules execution?

我很难理解为什么这个剪辑代码没有陷入无限循环

(defrule rule0
=>
        (assert (my-fact))
)

(defrule rule1
        ?f <- (my-fact)
=>
        (retract ?f)
)

据我所知,rule0 执行断言 my-fact 然后执行 rule1 收回它。 rule0 为什么现在不再执行?
以下是我的想法:

注意:这段代码是我从另一个使用模板而不是事实的小程序中抽象出来的。

你的第一个解释是可以接受的。规则不会针对同一组事实再次触发的原则称为 折射。对于相同的事实集,我不仅指相同的值,而且指相同的事实地址。

在这里,我们有一个特例。因为 rule0 没有 LHS,它不会触发第二次,即使事实库发生变化。没有 LHS 意味着没有模式匹配,因此没有进一步的激活。

但是您可以使用刷新命令再次触发规则。

CLIPS> (run)
CLIPS> (refresh rule0)
CLIPS> (agenda)
0      rule0: *
For a total of 1 activation.

通常情况下,如果相同的事实已经存在于您的事实库中,您将无法插入该事实(如果它已被撤回,您可以自由地再次添加)。 您可以使用 (set-fact-duplication):

更改它
CLIPS> (set-fact-duplication TRUE)

但我不推荐这样做。

维基百科很好地概述了 Rete 算法的工作原理。要理解的关键概念之一是,规则不寻找满足它们的数据,而是数据寻找它们满足的规则。 Rete 算法假定大多数数据在每次规则触发后保持不变,因此让规则寻找数据效率低下,因为在每次规则触发后只有一小部分数据发生变化。相反,规则会保存已经匹配的状态,并且当对数据进行更改影响该状态时,它会被更新。

当规则rule0被定义时,它被激活,因为它没有条件。当规则 rule1 被定义时,它没有被激活,因为 my-fact 还不存在。当规则 rule0 被执行时,事实 my-fact 被断言,然后规则 rule1 的状态被更新并被激活。当规则 rule1 被执行时,my-fact 被收回并且规则 rule1 的状态被更新,因为它匹配 my-fact。规则 rule0 不受此撤回的影响,因为它没有匹配 my-fact 的条件。