java 流口水规则流程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7754078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:16:52  来源:igfitidea点击:

drools rule flow

javarulesdrools

提问by Ricky Bobby

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

我在会话中插入 myData 和myData.getMyDog(),其中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)

第一条规则被解雇,我的狗将成为一个婴儿。然后第二个被触发,甚至打印 true 。(即使条件为假)

And when I test after firing all rules , myDog in myData is set to be a baby .

当我在触发所有规则后进行测试时, myData 中的 myDog 被设置为婴儿。

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 .

我想我需要说我修改了 myData:myDog 某处,但我不确定在哪里。

Hope my question is clear, if not tell me.

希望我的问题很清楚,如果没有告诉我。

回答by Dan Cruz

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 数据已更改,以便它可以重新评估所有相关规则。

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 dogrule, the myDog.isBaby() == falsecondition was true.

Drools 在触发任何匹配的规则之前评估事实。如果您有一只狗的年龄 = 0 和婴儿 = false,则您的两个规则都将被激活。当你的is my dog a baby?规则被触发时,它不会改变这样一个事实,即当 Drools 评估baby dog规则时,myDog.isBaby() == false条件为真。

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.myDogobject has changed, you'll need to use update()on the MyDataobject; just doing update()on your Dogobject, will not cause the baby dogrule to be re-evaluated.

要通知 Drools 您已经修改了某些事实,请使用update()知识助手方法。请记住,Drools 将事实句柄与特定对象相关联。如果规则引用MyData,并希望该规则进行重新评估,当MyData.myDog对象发生了变化,你需要使用update()的上MyData对象; 只是update()在你的Dog对象上做,不会导致baby dog规则被重新评估。

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

尝试将您的is my dog a baby?规则更改为以下内容:

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

回答by Augusto

You need to do

你需要做

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

on your first rule and rewrite the whenof 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.

规则必须以这种方式编写,因此 drools 可以自动检测在事实发生变化后必须再次运行哪些规则。

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.

我从版本 4 开始就没有使用过 drools,但我认为这仍然适用。

回答by salaboy

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

是的,您应该同时更新狗和地图。干杯

回答by Rizwan

You can update the dog in working memory by using modifyor updateknowledge 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

您可以使用modifyupdate知识助手方法更新工作记忆中的狗。如果您可以使用上述任何功能,Drools 将再次重新评估规则,您最终将陷入无限循环。所以你还需要你的规则中的无循环属性或修改你的条件

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

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.

以便下次它不会再次评估相同的规则并一次又一次地将 isBaby 更新为 true。