流口水规则流

2022-09-04 07:38:50

我有一个奇怪的流口水问题:

我有以下规则:

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

第一条规则被解除,我的狗被设定为一个婴儿。然后第二个被触发,即使它打印出真实 。(即使条件是假的)

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

我在这里做错了什么?为什么第二条规则被触发?会话中是否有问题(在我的情况下是有状态的)?

我认为我需要说我在某个地方修改了myData:myDog,但我不确定在哪里。

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


答案 1

当您修改工作记忆事实时,您需要告诉Drools数据已更改,以便它可以重新评估所有相关规则。

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

要通知 Drools 您修改了某些事实,请使用知识助手方法。请记住,Drools将事实句柄与特定对象相关联。如果规则引用 ,并且您希望在对象更改时重新评估该规则,则需要在对象上使用;只是在你的对象上做,不会导致规则被重新评估。update()MyDataMyData.myDogupdate()MyDataupdate()Dogbaby 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
    dog :    Dog( isBaby == false)
    myData : MyData( myDog == dog)

规则必须以这种方式编写,因此流口水可以自动检测在事实更改后必须再次运行哪些规则。

每次在规则引擎中更改事实时,都需要告诉工作内存您已经通过更新对其进行了更改。

自版本4以来,我没有使用过流口水,但我认为这仍然适用。


推荐