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?
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
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. –
stimme ich auch nicht zu, da die Situation (wie hier beschrieben) nicht reproduziert werden kann, d. H. Beide Regeln Feuer. – laune