2013-09-24 17 views
5

Próbuję grać na silniku reguł Drools, jestem całkiem początkującym.drools: zasady wykonywane więcej niż jeden raz

Mam następujące zasady w miejscu, w jednym pliku zasada:

rule "A stand alone rule" 
salience 2 
no-loop 
when 
    $account : Account() 
    Account($account.balance>100) 
then 
    System.out.println("balance>100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName());  
end 

rule "A second Rule" 
salience 1 
no-loop 
when 
    $account : Account() 
    Account($account.balance<100) 
then 
    System.out.println("balance<100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName()); 
end 

W StatefulKnowledgeSession jestem przechodzącej dwa konta, jedno z równowagi 15000 innego z wagą 15,

Account account=new Account(7l,15000l); 
     Account account1=new Account(5l,15l); 

     Customer customer = new Customer("Samrat", 28, "Sector51", account); 
     Customer customer1 = new Customer("Alexi", 28, "Sector50", account1); 
     account.setCustomer(customer); 
     account1.setCustomer(customer1); 
     session.insert(account); 
     session.insert(account1); 

     session.fireAllRules(); 

Według mnie oczekiwany wynik powinien polegać na tym, że każda reguła powinna zostać uruchomiona tylko raz, a odpowiedni obiekt powinien zostać wydrukowany.

Ale wynik otrzymuję to:

balance>100 
15000 
Samrat 
balance>100 
15000 
Samrat 
balance<100 
15 
Alexi 
balance<100 
15 
Alexi 

nie jestem w stanie zrozumieć, dlaczego każda reguła działa dwa razy ????

Odpowiedz

6

Użycie wielu wzorów (bez określania żadnej relacji między nimi) spowoduje utworzenie pełnego produktu kartezjańskiego (tak jak zaznaczenie w wielu tabelach bez klauzuli dołączenia). Tak więc zasada:

rule A 
when 
    Account() 
    Account() 
then 
    ... 
end 

zostanie aktywowane N^2 razy dla N obiektów typu rachunku. Jednym z rozwiązań mogłoby być użycie pola magicznego „to”, aby określić, że drugie konto jest taki sam jak pierwszy:

rule A 
when 
    $a: Account() 
    Account(this == $a) 
then 
    ... 
end 

Ale, wracając do przykładu, myślę, że nawet nie trzeba używać 2 różnych wzorów. Można przepisać reguł w następujący sposób:

rule "A stand alone rule" 
salience 2 
no-loop 
when 
    $account: Account(balance>100) 
then 
    System.out.println("balance>100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName());  
end 

rule "A second Rule" 
salience 1 
no-loop 
when 
    $account: Account(balance<100) 
then 
    System.out.println("balance<100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName()); 
end 

Nadzieja pomaga,

+0

Bang on! to naprawiło to! – Samrat

2

miałem porównanie dwóch obiektów tej samej klasy i zastanawiałem się, dlaczego te przepisy są wyrzucenie wielokrotnie. Jednak po przeczytaniu wyjaśnień od Estebana Alivertiego myślałem, że moja zasada może również tworzyć produkt kartezjański.

Wymieniłem "i" z zasad na "," i działało idealnie. Nie mogłem jednak zrozumieć, dlaczego "i" tworzyło produkt kartezjański.

Wcześniej moim reguły było -

rule "Rule 1" 
    when 
     $first : RuleC() and 
     second : RuleC(this != $first) and 
      RuleC($first.outcome < outcome) and 
      RuleC($first.target == target) 
    then 
     System.out.println("The rule has been fired "); 
end 

Później moja zasada stała się (i to działa absolutnie w porządku) -

rule "Rule 1" 
    when 
     $first : RuleC() and 
     second : RuleC(this != $first, $first.outcome < outcome, $first.target == target) 
    then 
     System.out.println("The rule has been fired "); 
end 
+0

W pierwszej regule każdy wzór zostanie dopasowany dla każdego obiektu RuleC w pamięci roboczej i jeśli ograniczenia będą zgodne, reguła zostanie uruchomiona. Podobnie jak w "jeśli istnieje obiekt Rule C (pierwszy) i jest obiekt Rule C, dla którego wynik

Powiązane problemy