【发布时间】: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