首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >流口水规则行为

流口水规则行为
EN

Stack Overflow用户
提问于 2022-11-24 04:08:28
回答 1查看 29关注 0票数 0

我们使用drools规则引擎5x我们有一个规则配置如下

事实{A,B,C},行动X事实{A,B},行动Z

当我通过{A,B,C}时,我得到了两个动作X,Z。这是drools引擎预期的行为吗?可以将C定义为可选事实吗?在这种情况下,这是可能的吗?

EN

回答 1

Stack Overflow用户

发布于 2022-11-30 15:27:21

工作正常。这两条规则都符合开火的条件,所以这两条规则都是开火的。

如果您不希望在传递C条件时触发AB规则,则需要编写它,这样它就不会显式地触发。

下面是一个例子:

代码语言:javascript
复制
rule "ABC"
when
  A()
  B()
  C()
then
  System.out.println("ABC");
end

rule "AB not C"
when
  A()
  B()
  not( C() )
then
  System.out.println("AB not C");
end

在本例中,如果将对象ABC传递到规则中,则只会触发第一个规则,因为第二个规则是相互排斥的:只有在不存在C时才会触发。类似地,如果您只传递AB,而不传递C,那么只有第二个规则会触发,因为第一个规则需要C,并且没有满足要求。

如果没有not( C() )条件,那么您在示例中就有了:规则将触发,而不管C对象在内存中的存在(或脓肿),因为它是完全无关的。你会问你是否可以让C是可选的--正如你所拥有的,C是可选的。它是否存在并不重要。

请注意,您如何否定条件"C“取决于它实际上是什么。如果您的事实是这样的:MyObj( a == 1, b == 2, c >= 3),那么您将通过在:MyObj( a == 1, b == 2, c < 3)上设置AB规则键来否定C。您只需反转"C“条件检查,不管它是什么。

为了完整起见,值得一提的是,您可以修改工作内存中的项,以防止第二条规则在第一条规则发生后触发。如果这两条规则生活在真空中,这可能会成为你的解决方案;如果它们是一个更大的规则集的一部分,可能会有其他规则依赖于这些相同的事实,这可能会导致意想不到的后果。

首先,您可以在工作内存中插入一个“标志”,并在您不想触发的规则中关闭它的存在(或不存在)。因此,如果不希望AB触发,如果ABC被触发,则可以在ABC规则的右侧插入一个标志:

代码语言:javascript
复制
declare Flag
  name: String
end

rule "ABC with flag"
when
  A()
  B()
  C()
then
  Flag f = new Flag();
  f.setName("ABC");
  insert( f )
end

rule "AB but not if ABC"
when
  A()
  B()
  not( Flag(name = "ABC" ))
then
  //...
end

在这里,规则ABC在发射时插入一个标志;规则AB在发射之前检查是否存在该标志。

或者,您可以从工作内存中提取retract事实,以便不再触发要求该数据的规则。这可能会产生深远的后果(数据实际上是从工作内存中删除的,因此当Drools重新评估所有有效规则时,可能会触发意外的规则),因此通常不建议您这样做。

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

https://stackoverflow.com/questions/74555512

复制
相关文章

相似问题

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