首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >剪辑如何不重复执行规则?

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

Stack Overflow用户
提问于 2018-06-11 03:01:36
回答 2查看 466关注 0票数 0

我很难理解为什么这段剪辑代码不会陷入无限循环

代码语言:javascript
复制
(defrule rule0
=>
        (assert (my-fact))
)

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

据我所知,rule0是在断言my-fact的情况下执行的,然后rule1是在撤销它的情况下执行的。为什么rule0现在不再执行一次?

以下是我的想法:

  • Clip会记住使用某些基本事实执行的每个规则,并避免使用相同的基本事实重新执行此规则。
  • 有某种优化器可以检测到循环并避免它。
  • Clip会记住插入和删除的事实,并避免重新插入这些事实(高度怀疑,我几乎可以肯定不会出现这种情况)。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-12 00:58:27

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

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

票数 2
EN

Stack Overflow用户

发布于 2018-06-11 06:52:40

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

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

但您可以使用refresh命令再次触发规则。

代码语言:javascript
复制
CLIPS> (run)
CLIPS> (refresh rule0)
CLIPS> (agenda)
0      rule0: *
For a total of 1 activation.

通常,如果factbase中已经存在相同的事实,则不能插入该事实(如果该事实已被撤回,您可以自由地再次添加它)。您可以使用(set-fact-duplication)进行更改:

代码语言:javascript
复制
CLIPS> (set-fact-duplication TRUE)

但我不建议这样做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50787097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档