【问题标题】:Drools rule behaviourDrools 规则行为
【发布时间】:2022-11-30 23:27:21
【问题描述】:

我们正在使用 drools 规则引擎 5x 我们有一个配置的规则

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

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

【问题讨论】:

  • 这种行为是预期的。

标签: drools


【解决方案1】:

这种行为是预期的。 看来你想要的正是这样的东西: 如果 Rule1 Fact(A,B,C) 和 Rule2 Fact(A,B) 一起为真,则只有 Rule1 Fact(A,b,C) 触发。

这就像规则覆盖。使用#drools 是不可能的。可以使用其他工具,例如 #ibmodm。

我想写你想做的事情的更简单的方法是写: 事实(A、B 而不是 C)行动 Z。

希望这可以帮助, 伊曼纽尔

【讨论】:

【解决方案2】:

这工作正常。两条规则都满足触发条件,因此两条规则都会触发。

如果您不希望 AB 规则在 C 条件通过时触发,则需要将其编写为明确不触发。

这是一个例子:

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),那么你可以通过打开 AB 规则键来否定 C:MyObj( a == 1, b == 2, c < 3)。您只需要反转“C”条件检查,无论它是什么。


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

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

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 重新评估所有规则是否有效时,您可能会触发意外规则),因此通常不建议您这样做。

【讨论】:

    猜你喜欢
    • 2019-04-08
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    相关资源
    最近更新 更多