流口水规则流
Posted
技术标签:
【中文标题】流口水规则流【英文标题】:drools rule flow 【发布时间】:2011-12-06 22:23:26 【问题描述】:我对流口水有一个奇怪的问题:
我有以下规则:
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
我在会话中插入 myData 和 myData.getMyDog()
,其中 myData.getMyDog.isBaby==false
第一条规则被触发,我的狗被设置为婴儿。然后第二个被触发,甚至它打印 true 。(即使条件是 false)
当我在触发所有规则后进行测试时,myData 中的 myDog 被设置为婴儿。
我在这里做错了什么?为什么会触发第二条规则?是会话中的问题(在我的情况下是有状态的)吗?
我认为我需要说我在某处修改了 myData:myDog,但我不确定在哪里。
希望我的问题很清楚,如果不告诉我。
【问题讨论】:
【参考方案1】:当您修改工作记忆事实时,您需要告诉 Drools 数据已更改,以便它可以重新评估所有相关规则。
Drools 在触发任何匹配的规则之前评估事实。如果您的狗的年龄 = 0 且婴儿 = false,则您的两条规则都将被激活。当您的 is my dog a baby?
规则被触发时,它不会改变这样一个事实,即当 Drools 评估 baby dog
规则时,myDog.isBaby() == false
条件为真。
要通知 Drools 你已经修改了一些事实,请使用update()
知识助手方法。请记住,Drools 将事实句柄与特定对象相关联。如果规则引用MyData
,并且您希望在MyData.myDog
对象发生更改时重新评估该规则,则需要在MyData
对象上使用update()
;只是对您的 Dog
对象执行 update()
,不会导致重新评估 baby dog
规则。
尝试将您的 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
【讨论】:
非常感谢,我要试试这个【参考方案2】:你需要做的
then
dog.setIsBaby(true);
update( dog )
在您的第一条规则上并重写第二条规则的 when,例如
when
dog : Dog( isBaby == false)
myData : MyData( myDog == dog)
规则必须以这种方式编写,因此 Drools 可以自动检测在事实发生变化后它必须再次运行哪些规则。
每次你在规则引擎中改变一个事实,你需要告诉工作记忆你已经用更新改变了它。
我从第 4 版开始就没有使用过 drools,但我认为这仍然适用。
【讨论】:
非常感谢,我要试试这个【参考方案3】:是的,您应该同时更新狗和地图。 干杯
【讨论】:
【参考方案4】:您可以使用modify
或update
知识助手方法更新工作记忆中的狗。如果您可以使用上述任何功能,Drools 将再次重新评估规则,最终您将陷入无限循环。因此,您还需要在规则中添加无循环属性或将条件修改为
dog : Dog(age <1, isBaby == false )
这样下一次它就不会再次评估相同的规则并一次又一次地将 isBaby 更新为 true。
【讨论】:
以上是关于流口水规则流的主要内容,如果未能解决你的问题,请参考以下文章