开发者

drools rule flow

开发者 https://www.devze.com 2023-04-12 14:31 出处:网络
I\'m having a strange issue with drools : I have the following rules : rule \"is my dog a baby?\" ruleflow-group \"dog\"

I'm having a strange issue with drools :

I have the following rules :

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

I insert in my session myData and myData.getMyDog(), where myData.getMyDog.isBaby==false

The first rule is fired and my dog is set to be a baby. Then the second one is fired, and even it prints true .(even if the condition was to be false)

And when I test after firing all rules , myDog 开发者_JS百科in myData is set to be a baby .

What am I doing wrong here ? Why does the second rule is fired ? is the problem in the session (stateful in my case) ?

I think that I need to say that I modify myData:myDog somewhere ,but I am not sure where .

Hope my question is clear, if not tell me.


When you modify working memory facts, you need to tell Drools that the data has changed so it can re-evaluate all relevant rules.

Drools evaluates facts before firing any matched rules. If you have a dog with age = 0 and baby = false, both your rules will be activated. When your is my dog a baby? rule is fired, it doesn't change the fact that when Drools evaluated the baby dog rule, the myDog.isBaby() == false condition was true.

To inform Drools that you have modified some fact, use the update() knowledge helper method. Keep in mind that Drools associates fact handles to a specific object. If a rule references MyData, and you want that rule to be re-evaluated when the MyData.myDog object has changed, you'll need to use update() on the MyData object; just doing update() on your Dog object, will not cause the baby dog rule to be re-evaluated.

Try changing your is my dog a baby? rule to the following:

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


You need to do

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

on your first rule and rewrite the when of your second rule like

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

The rule has to be written in this way, so drools can automatically detect which rules it has to run again after a fact changes.

Every time you change a fact in the rules engine, you need to tell the working memory that you've changed it with update.

I haven't used drools since version 4, but I assume that this still applies.


Yes you should update both the dog and the map. Cheers


You can update the dog in working memory by using modify or update knowledge helper methods. If you can any of the above function Drools will re-evaluate the rules again and you will end up with an infinite loop. so you also need to you no-loop attribute in your rule or modify you condition to

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

so that the next time it will not evaluate the same rule again and update the isBaby to true again and again.

0

精彩评论

暂无评论...
验证码 换一张
取 消