2011-10-13 22 views
12

estoy teniendo un problema extraño con drools:drools regla de flujo

tengo las siguientes reglas:

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 

inserto en mi sesión de myData y myData.getMyDog(), donde myData.getMyDog.isBaby==false

La primera se dispara la regla y mi perro se convertirá en un bebé. Luego, el segundo se dispara, e incluso se imprime verdadero. (Incluso si la condición fuera falsa)

Y cuando pruebo después de activar todas las reglas, myDog en myData está configurado para ser un bebé.

¿Qué estoy haciendo mal aquí? ¿Por qué se dispara la segunda regla? es el problema en la sesión (con estado en mi caso)?

Creo que tengo que decir que modifico myData: myDog en alguna parte, pero no estoy seguro de dónde.

Espero que mi pregunta sea clara, si no me lo dices.

Respuesta

15

Cuando modifica hechos de la memoria de trabajo, necesita decirle a Drools que los datos han cambiado para que pueda volver a evaluar todas las reglas relevantes.

Drools evalúa los hechos antes de disparar las reglas coincidentes. Si tienes un perro con edad = 0 y bebé = falso, ambas reglas se activarán. Cuando se activa su regla is my dog a baby?, no cambia el hecho de que cuando Drools evaluó la regla baby dog, la condición myDog.isBaby() == false fue verdadera.

Para informar a Drools que ha modificado algún hecho, utilice el método de conocimiento update(). Tenga en cuenta que Drools asocia identificadores de hechos a un objeto específico. Si una regla hace referencia a MyData, y desea que esa regla se vuelva a evaluar cuando el objeto MyData.myDog ha cambiado, deberá usar update() en el objeto MyData; solo haciendo update() en su objeto Dog, no hará que la regla baby dog sea reevaluada.

trate de cambiar su estado is my dog a baby? a lo siguiente:

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

Muchas veces lo intentaré –

9

lo que necesita hacer

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

en su primera regla y reescribir el cuando de la segunda regla como

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

La regla tiene que ser escrita de esta manera, por lo que babea puede detecta automáticamente qué reglas debe ejecutar nuevamente después de que un hecho cambie.

Cada vez que cambia un hecho en el motor de reglas, necesita decirle a la memoria de trabajo que lo ha cambiado con la actualización.

No he usado babas desde la versión 4, pero supongo que esto sigue siendo válido.

+0

Muchas veces voy a intentarlo –

2

Sí se debe actualizar el perro y el mapa. Cheers

0

Puede actualizar el perro en la memoria de trabajo utilizando los métodos modify o update knowledge helper. Si puede cualquiera de las funciones anteriores, Drools volverá a evaluar las reglas y terminará con un ciclo infinito. por lo que también es necesario para que ningún bucle atributo en la regla o modificar condicionas a

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

para que la próxima vez no se evaluará la misma regla de nuevo y actualizar el isBaby a la verdadera y otra vez.

Cuestiones relacionadas