我很难理解为什么这段剪辑代码不会陷入无限循环
(defrule rule0
=>
(assert (my-fact))
)
(defrule rule1
?f <- (my-fact)
=>
(retract ?f)
)
据我所知,rule0
是在断言my-fact
的情况下执行的,然后rule1
是在撤销它的情况下执行的。为什么rule0
现在不再执行一次?
以下是我的想法:
注意:我从另一个使用模板而不是事实的小程序中抽象出这段代码。
发布于 2018-06-12 00:58:27
维基百科很好地概述了Rete算法是如何工作的。要理解的关键概念之一是,规则不寻求满足它们的数据,而是数据寻找它们满足的规则。Rete算法假设大多数数据在每次规则触发后保持不变,因此让规则查找数据将是低效的,因为在每次规则触发后只有一小部分数据发生更改。相反,规则保存已经匹配的内容的状态,当对数据进行影响该状态的更改时,将更新该状态。
当定义规则rule0时,它会被激活,因为它没有任何条件。定义规则事实时,它不会被激活,因为my- rule1还不存在。当执行规则rule0时,将断言事实my-fact,然后规则rule1将更新其状态并被激活。当执行规则rule1时,将收回my-fact,并更新规则rule1的状态,因为它与my-fact匹配。规则事实不受此撤销的影响,因为它没有与my- rule0匹配的条件。
发布于 2018-06-11 06:52:40
你的第一个解释是可以接受的。规则不会对同一组事实第二次触发的原理称为折射。对于相同的事实集,我指的不仅是相同的值,而且还有相同的事实地址。
在这里,我们有一个特例。因为rule0没有LHS,所以即使事实基础发生变化,它也不会第二次触发。没有LHS意味着没有模式匹配,因此没有进一步的激活。
但您可以使用refresh命令再次触发规则。
CLIPS> (run)
CLIPS> (refresh rule0)
CLIPS> (agenda)
0 rule0: *
For a total of 1 activation.
通常,如果factbase中已经存在相同的事实,则不能插入该事实(如果该事实已被撤回,您可以自由地再次添加它)。您可以使用(set-fact-duplication)进行更改:
CLIPS> (set-fact-duplication TRUE)
但我不建议这样做。
https://stackoverflow.com/questions/50787097
复制相似问题