2016-04-25 66 views
0

使用drools 6.4-FINALDrools條件衝突/消費事實?

我們有兩條規則;

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規則2火災
  • 如果類A,提供B,C和X無規則fi即使Rule1應該有。
  • 刪除規則2允許規則1在提供A,B,C和X時觸發。
  • 在文件中按順序交換規則會顛倒上述行爲(即使Rule2應該這樣做,X = Rule1觸發,Y =不觸發)。
  • 再次按照相反的順序,刪除第二個規則允許第一個觸發。

任何人都可以解釋這裏發生了什麼。雖然我懷疑訂單是一個紅色的鯡魚,但它看起來像試圖匹配消費事實的第一條規則,或者在將事實分配給變量時存在一些衝突。

UPDATE

經過進一步調查我過於簡化上面的代碼。而不是在BClass中枚舉比較,實際上有一個吸氣器,

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

而規則BClass行實際上讀取;

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

我們已將問題細化到BClass線。類比較某種程度上消耗或衝突。增加相同格式的更多規則(如規則3,規則4)只會加劇問題。進一步減少刪除其唯一區分類(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類比較條件並重新運行測試將按照預期觸發全部規則。

這似乎很奇怪的行爲,考慮到一個規則觸發,類比較有效,但只有一個規則?

+0

這不能被再現,除非你提供類A和B的精確代碼和AType和BType枚舉。 – laune

+0

我不同意,鑑於這兩個規則的前三個條件是相同的,他們的實際執行是不相關的。也許我應該進一步簡化,只留下CClass,問題的關鍵在於,給定近似匹配條件的兩條規則似乎阻止了另一條規則。 –

+0

我也不同意,因爲情況(如此處所述)無法複製,即兩條規則都會觸發。 – laune

回答

0

這是一個錯誤,至少在6.3.0和6.4.0。

這很有意思:只要有兩個相同的LHS,都是火;如果沒有使用java.lang類型的字段的約束。類沒關係;只有存在這樣的約束並且如果有三條規則,則兩個激活被丟棄。

結論

該錯誤被報告爲口水-1144和固定經由上拉請求可用https://github.com/droolsjbpm/drools/pull/763

+0

我報告過這個錯誤。 – laune

+0

我已被告知類似的錯誤已被修復。確認此修補程序也可以在24小時內解決您的ABC錯誤。 – laune

+0

更新:這一個似乎是一個新的。 - 只有一個B模式可以觸發,只有一個約束比較它們三個中的configClass == Config.class。敬請關注。 – laune