2011-10-13 9 views
12

sto avendo un problema strano con sbava:sbava legge di flusso

ho le seguenti regole:

rule "is my dog a baby?" 
    ruleflow-group "dog" 
    salience 10 
    when 
    dog : Dog(age <1) 
    then 
    dog.setIsBaby(true); 
end 


rule "baby dog" 
    ruleflow-group "dog" 
    salience 9 
    when 
     myData : MyData(myDog.isBaby() == false) 
    then 
     System.out.println(myData.getMyDog().getIsBaby()); 
end 

inserisco nella mia sessione myData e myData.getMyDog(), dove myData.getMyDog.isBaby==false

La prima la regola è licenziata e il mio cane è impostato per essere un bambino. Poi viene sparato il secondo e anche quello vero (anche se la condizione doveva essere falsa)

E quando provo dopo aver attivato tutte le regole, myDog in myData è impostato per essere un bambino.

Cosa sto facendo di sbagliato qui? Perché viene licenziata la seconda regola? è il problema nella sessione (stateful nel mio caso)?

Penso di aver bisogno di dire che modifico myData: myDog da qualche parte, ma non sono sicuro di dove.

Spero che la mia domanda sia chiara, se non mi dite.

risposta

15

Quando si modificano i dati della memoria di lavoro, è necessario comunicare a Drools che i dati sono stati modificati in modo da poter rivalutare tutte le regole pertinenti.

Drools valuta i fatti prima di attivare le regole corrispondenti. Se hai un cane con età = 0 e bambino = falso, entrambe le regole saranno attivate. Quando viene attivata la regola is my dog a baby?, ciò non cambia il fatto che quando Drools ha valutato la regola baby dog, la condizione myDog.isBaby() == false era vera.

Per informare Drools della modifica di alcuni fatti, utilizzare il metodo di supporto della conoscenza update(). Ricorda che Drools associa gli handle di fatto a un oggetto specifico. Se una regola fa riferimento a MyData e si desidera rivalutare quella regola quando l'oggetto MyData.myDog è stato modificato, sarà necessario utilizzare update() sull'oggetto MyData; semplicemente facendo update() sull'oggetto Dog, la regola baby dog non verrà rivalutata.

Provare a cambiare la regola is my dog a baby? al seguente:

rule "is my dog a baby?" 
    ruleflow-group "dog" 
    salience 10 
    when 
     dog : Dog(age < 1, baby == false) 
     myData : MyData(myDog == dog) 
    then 
     dog.setIsBaby(true); 
     update(dog); 
     update(myData); 
    end 
+0

Thx molto ho intenzione di provare che –

9

Hai bisogno di fare

then 
    dog.setIsBaby(true); 
    update(dog) 

sulla vostra prima regola e riscrivere la quando della vostra seconda regola come

when 
    dog : Dog(isBaby == false) 
    myData : MyData(myDog == dog) 

La regola deve essere scritto in questo modo, così drools può rileva automaticamente quali regole deve essere eseguita di nuovo dopo che un fatto cambia.

Ogni volta che si modifica un fatto nel motore delle regole, è necessario indicare alla memoria di lavoro che è stato modificato con l'aggiornamento.

Non ho usato drools dalla versione 4, ma presumo che ciò sia ancora valido.

+0

Thx molto ho intenzione di provare questo –

2

Sì è necessario aggiornare sia il cane e la mappa. Cheers

0

È possibile aggiornare il cane nella memoria di lavoro utilizzando i metodi di supporto di conoscenza modify o update. Se puoi eseguire una qualsiasi delle funzioni sopra descritte, Drools rivaluterà nuovamente le regole e finirai con un ciclo infinito. quindi è necessario anche a voi non-loop attributo la regola o modificare si condizione

dog : Dog(age <1, isBaby == false)

modo che la prossima volta non valuterà nuovamente la stessa regola e aggiornare l'isBaby true ancora e ancora.