2011-10-13 166 views
12

我在與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 

我插入我的會議myData的和myData.getMyDog(),其中myData.getMyDog.isBaby==false

第一規則被解僱,我的狗被定爲嬰兒。然後第二個被解僱,甚至它打印真實(即使條件是假的)

而且當我測試完所有規則後,myData中的myDog被設置爲一個嬰兒。

我在這裏做錯了什麼?爲什麼第二條規則被解僱?是會話中的問題(在我的情況下是有狀態的)?

我認爲我需要說我修改myData:myDog的某處,但我不確定它在哪裏。

希望我的問題很明確,如果不告訴我的話。

回答

15

當您修改工作記憶事實時,您需要告訴Drools數據已更改,以便重新評估所有相關規則。

Drools在發佈任何匹配規則之前評估事實。如果您的年齡= 0,寶寶=假的狗,您的規則將被激活。當您的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 
+0

Thx很多我會嘗試 –

9

你需要做的第一條規則

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

和重寫你的第二個規則的

when 
    dog : Dog(isBaby == false) 
    myData : MyData(myDog == dog) 

該規則以這種方式來寫的,所以滴料能自動檢測事實發生變化後必須再次運行哪些規則。

每次您在規則引擎中更改事實時,都需要告訴工作內存您已更新了更新。

我從版本4開始就沒有使用drools,但我認爲這仍然適用。

+0

Thx很多我要去嘗試 –

2

是的,你應該同時更新狗和地圖。 乾杯

0

您可以使用modifyupdate知識幫手方法更新工作記憶中的狗。如果您可以使用上述任何一種功能,Drools會重新評估規則,最終會出現無限循環。所以你還需要你無環屬性,在規則或修改你一次又一次條件

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

,這樣下一次就不會再評估相同的規則,並更新isBaby爲true。