流口水

Ric*_*bby 12 java rules drools

我对drools有一个奇怪的问题:

我有以下规则:

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
Run Code Online (Sandbox Code Playgroud)

我插入我的会话myData和myData.getMyDog(),在哪里myData.getMyDog.isBaby==false

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

当我在解决所有规则后进行测试时,myData中的myDog将被设置为婴儿.

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

我想我需要说我修改了myData:myDog,但我不知道在哪里.

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

Dan*_*ruz 15

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

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

要告知Drools您已修改了某些事实,请使用update()知识帮助程序方法.请记住,Drools将事实句柄与特定对象相关联.如果规则引用MyData,并且您希望在MyData.myDog对象更改时重新评估该规则,则需要update()在该MyData对象上使用; 只是update()对你的Dog对象做,不会导致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
Run Code Online (Sandbox Code Playgroud)


Aug*_*sto 9

你需要这样做

then 
    dog.setIsBaby(true);
    update( dog ) 
Run Code Online (Sandbox Code Playgroud)

你的第一条规则改写的时候你喜欢第二个规则

when
    dog :    Dog( isBaby == false)
    myData : MyData( myDog == dog)
Run Code Online (Sandbox Code Playgroud)

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

每次更改规则引擎中的事实时,您都需要告诉工作内存您已通过更新更改了它.

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