【问题标题】:Drools Condition conflicts / consuming facts?Drools 条件冲突/消耗事实?
【发布时间】:2016-04-25 15:43:46
【问题描述】:

使用流口水 6.4-FINAL

我们有两条规则;

rule "Rule1"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(type == BType.SHIP);
    $cclass: CClass();
    $xclass: XClass();
then
    //actions       
    System.out.println("Actioning Rule1");
end

rule "Rule2"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(type == BType.SHIP);
    $cclass: CClass();
    $yclass: YClass();
then
    //actions
    System.out.println("Actioning Rule2");
end

请注意,两个规则的前 3 个条件是相同的(在类 AClass、BClass 和 CClass 的某些情况下匹配类类型和内部类型。 事实中存在 XClass 或 YClass 的规则有所不同。

我们发现以下行为;

  • 如果提供了 A、B、C 和 Y 类,则 Rule2 触发。
  • 如果提供了 A、B、C 和 X 类,则不会触发任何规则,即使 Rule1 应该有。
  • 删除 Rule2 允许 Rule1 在提供 A、B、C 和 X 时触发。
  • 按文件中的顺序交换规则会反转上述行为(X = Rule1 触发,Y = 即使 Rule2 应该触发也不触发)。
  • 再次以相反的顺序,删除第二个规则允许第一个触发。

谁能解释这里发生了什么。虽然我怀疑排序是一个红鲱鱼,但它看起来确实尝试匹配的第一条规则以某种方式消耗了事实,或者在将事实分配给变量时存在一些冲突。

更新

经过进一步调查,我过度简化了上面的代码。而不是 BClass 中的枚举比较,实际上有一个吸气剂;

    public Class<?> getConfigClass() {
        return BConfig.class;
    }

而规则 BClass 行实际上是这样写的;

$bclass: BClass(configClass == BConfig.class);

我们已将问题细化到 BClass 行。类比较以某种方式消耗或冲突。添加更多相同格式的规则(比如 Rule3、Rule4)只会加剧问题。进一步减少规则以删除它们唯一的区别类(X或Y);

rule "Rule1"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(configClass == BConfig.class);
    $cclass: CClass();
then
    //actions       
    System.out.println("Actioning Rule1");
end

rule "Rule2"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(configClass == BConfig.class);
    $cclass: CClass();
then
    //actions
    System.out.println("Actioning Rule2");
end

rule "Rule3"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(configClass == BConfig.class);
    $cclass: CClass();
then
    //actions
    System.out.println("Actioning Rule3");
end

传递满足这 3 个条件的事实(即 AClass 与 getType == AType.DOG,BClass 与 getConfigClass == BConfig.class 和一个 CClass)总是运行最后一条规则,无论如何有很多规则。

删除 BClass 类比较条件并重新运行测试会按预期触发 所有 规则。

鉴于触发了一条规则,类比较有效,但仅适用于一条规则,这似乎是非常奇怪的行为?

【问题讨论】:

  • 除非您提供 A 类和 B 类以及 AType 和 BType 枚举的确切代码,否则无法复制。
  • 我不同意,鉴于两个规则中的前三个条件相同,它们的实际实现无关紧要。也许我应该进一步简化,只留下 CClass 在那里,问题的关键是这两个规则,给定几乎匹配的条件,似乎阻止了另一个。
  • 我也不同意,因为情况(如此处所述)无法重现,即两个规则都会触发。
  • 好吧,抱歉,我似乎对我们的实际代码过度简化了代码。请参阅有关班级比较的更新。

标签: drools


【解决方案1】:

这是一个错误,至少在 6.3.0 和 6.4.0 中是这样。

这很有趣:只要只有两个相同的 LHS,它们都会着火;如果没有使用 java.lang.Class 类型的字段的约束,则可以;仅当存在这样的约束并且存在三个规则时,才会丢弃两个激活。

结论

该错误被报告为 DROOLS-1144,可通过拉取请求 https://github.com/droolsjbpm/drools/pull/763 获得修复

【讨论】:

  • 我已经报告了这个错误。
  • 我被告知一个类似的错误已经修复。确认此修复程序也可以解决您的 ABC 错误将在 24 小时内完成。
  • 更新:这个好像是新的。 - 可以由一个 B 模式触发,其中一个约束比较所有三个中的 `configClass == Config.class。敬请期待。
猜你喜欢
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 2015-07-07
  • 2018-08-29
  • 2018-01-19
  • 2012-04-26
  • 2016-04-03
  • 2019-10-29
相关资源
最近更新 更多