2016-04-25 8 views
0

Verwendung von Drools 6.4-FINALDrools Zustandskonflikte/Fakten verbrauchen?

Wir haben zwei Regeln;

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 

Hinweis, daß die ersten 3 Bedingungen der beiden Regeln sind die gleichen (Anpassung der Classtype über und eine innere Typ in einigen Fällen von Klassen AClass, BKlasse und CClass. Die Regeln unterscheiden sich mit XClass oder YClass vorliegt . in den Tatsachen

finden wir das folgende Verhalten,.

  • Wenn die Klassen A, B, C und Y vorgesehen sind Rule2 Brände
  • Wenn die Klassen A, B, C und X vorgesehen sind keine Regeln fi re, obwohl Rule1 hätte.
  • Durch das Löschen von Rule2 kann Rule1 ausgelöst werden, wenn A, B, C und X bereitgestellt werden.
  • Der Austausch der Regeln in ihrer Reihenfolge in der Datei kehrt das obige Verhalten um (X = Rule1 feuert, Y = kein Feuer, obwohl Rule2 dies tun sollte).
  • Auch in dieser umgekehrten Reihenfolge erlaubt das Löschen der zweiten Regel, dass die erste ausgelöst wird.

Kann mir jemand erklären, was hier vor sich geht. Während ich vermute, dass die Reihenfolge ein Ablenkungsmanöver ist, sieht es so aus, als ob die erste Regel, die versucht, eine Übereinstimmung zu finden, die Fakten irgendwie konsumiert, oder es gibt einen Konflikt bei der Zuordnung von Fakten zu Variablen.

UPDATE

Nach einer weiteren Untersuchung stark vereinfacht ich den obigen Code. Anstatt einen Vergleich in BClass zu finden, gibt es tatsächlich einen Getter, so dass;

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

Und die Regeln BClass Zeile tatsächlich liest;

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

Wir haben das Problem bis zur BClass-Linie verfeinert. Der Klassenvergleich verbraucht irgendwie oder Konflikte. Das Hinzufügen weiterer Regeln (zB Rule3, Rule4) desselben Formats verschärft das Problem nur noch. Weitere Reduzierung der Regeln, um ihre einzige differenzierende Klasse (X oder Y) zu entfernen;

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 

Passing in Tatsachen, die diese drei Bedingungen (dh AClass mit getType == AType.DOG, B-Klasse mit getConfigClass == BConfig.class und einer C-Klasse) immer erfüllen läuft die letzte Regel, egal wie viele Regeln gibt es.

Die BClass Klassenvergleichsbedingung entfernen und den Test erneut ausführen alle Regeln wie erwartet.

Es scheint sehr seltsames Verhalten, dass, da eine Regel ausgelöst wird, der Klassenvergleich ist gültig, aber nur für eine Regel?

+0

Dies kann nicht reproduziert werden, wenn Sie den genauen Code für die Klassen A und B zur Verfügung stellen und die Typen AType und BType. – laune

+0

Ich stimme nicht zu, da die ersten drei Bedingungen in beiden Regeln gleich sind ihre tatsächliche Umsetzung ist irrelevant. Vielleicht hätte ich weiter vereinfacht und nur CClass drin gelassen, der Punkt der Frage ist, dass die beiden Regeln, bei nahezu übereinstimmenden Bedingungen, auf einem anderen zu blockieren scheinen. –

+0

stimme ich auch nicht zu, da die Situation (wie hier beschrieben) nicht reproduziert werden kann, d. H. Beide Regeln Feuer. – laune

Antwort

0

Dies ist ein Fehler, zumindest in 6.3.0 und 6.4.0.

Es ist ziemlich interessant: solange es nur zwei identische LHS gibt, feuern beide; wenn es keine Einschränkung gibt, die ein Feld vom Typ java.lang verwendet.Klasse, es ist in Ordnung; Nur wenn es eine solche Einschränkung gibt und wenn es drei Regeln gibt, werden zwei Aktivierungen verworfen.

Fazit

Der Fehler als drools-1144 berichtet wurde und das Update ist über den Pull Anfrage https://github.com/droolsjbpm/drools/pull/763

+0

Ich habe den Fehler gemeldet. – laune

+0

Ich wurde informiert, dass ein ähnlicher Fehler behoben wurde. Bestätigung, dass dieses Update auch Ihren ABC-Fehler behebt, wird innerhalb von 24 Stunden kommen. – laune

+0

Update: Dieser scheint ein neuer zu sein. - Kann von nur einem B-Muster mit einer einzigen Einschränkung ausgelöst werden, indem man 'configClass == Config.class in allen drei vergleicht. Bleib dran. – laune