Drools条件冲突/消费事实?

时间:2016-04-25 15:43:47

标签: drools

使用drools 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的某些情况下匹配classtype和内部类型。 规则不同,XClass或YClass存在于事实中。

我们发现了以下行为;

  • 如果提供A,B,C和Y类,则会触发Rule2。
  • 如果提供了A,B,C和X类,即使Rule1应该有,也没有规则触发。
  • 删除Rule2允许在提供A,B,C和X时触发Rule1。
  • 在文件中按顺序交换规则会颠倒上述行为(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个条件的事实(即带有getType == AType.DOG的AClass,带有getConfigClass == BConfig.class和CClass的BClass)总是运行最后一条规则,无论如何有很多规则。

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

似乎非常奇怪的行为,如果一个规则触发,类比较 有效,但仅适用于一个规则?

1 个答案:

答案 0 :(得分:0)

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

非常有趣:只要有两个完全相同的LHS,两者都会开火;如果没有使用java.lang.Class类型的字段的约束它可以;只有当存在这样的约束并且如果有三个规则时,才会删除两个激活。

<强>结论

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

获取