流口水规则流

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】:

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

dog : Dog(age &lt;1, isBaby == false )

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

【讨论】:

以上是关于流口水规则流的主要内容,如果未能解决你的问题,请参考以下文章

jbpm 进程未使用 ruleFlowGroup 触发流口水规则

流口水规则的意外输出

使用junit进行流口水测试

如何在流口水规则引擎中处理列表项中对象的先前值?

流口水 vs JBPM ?差异,优点和缺点

Drools 规则流程设计