2012-10-17 24 views
1

在不工作我有兩個非常簡單的規則Drools的像廣告專家文檔

rule "Volume Validation" 
    salience 10 
when 

    avs : AvailabilityStatusAndDiscountDisplay(quantity > 1000 || quantity < 0) 

then  

    avs.setAvailable(false);   
    avs.setDiscountRateUnavailableMessage("Unavailable Quanitity"); 
end 

rule "Discount Rate Calculation -1" 

salience 9 

when 

    AvailabilityStatusAndDiscountDisplay(productType == "111",calculated==false, available == true, quantity >= 50) 

    avs: AvailabilityStatusAndDiscountDisplay() 
then  

    avs.setDiscountRate("0.65"); 
    avs.setCalculated(true); 

end 

但是當數量爲5000,可通過第一規則設置爲false。第二條「規則」不能看到這種變化並繼續進行評估。 儘管https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_SOA_Platform/5/html/JBoss_Rules_5_Reference_Guide/chap-examples.html#id18463514表示在工作內存中更改的對象將被序列中的下一個規則看到。

編輯。非常感謝@alicox的幫助

rule "Volume Validation" 
salience 10 
no-loop true 
when 

avs : AvailabilityStatusAndDiscountDisplay(quantity > 1000 || quantity < 0) 

then  

avs.setAvailable(false);   
avs.setDiscountRateUnavailableMessage("Unavailable Quanitity"); 
update(avs); 
end 

rule "Discount Rate Calculation -1" 

salience 9 

when 

AvailabilityStatusAndDiscountDisplay(productType == "111",calculated==false, available == true, quantity >= 50) 

avs: AvailabilityStatusAndDiscountDisplay() 
then  

avs.setDiscountRate("0.65"); 
avs.setCalculated(true); 

end 

This works。

alicox也提出了建議,通過插入方法來創建麪包屑,如果我理解正確的是這樣

then 
    insert (blah = true) //so as not to fire new rule 
    end 
//new rule 
when 
    blah == false 

不知道但什麼樣的對象必須是。

回答

1

更改其屬性後,您需要在avs上調用update或modify,以便在LHS部分重新評估它。

在你的第二個規則LHS

也可以縮短到以下幾點:

avs: AvailabilityStatusAndDiscountDisplay(productType == "111", 
      calculated==false, available == true, quantity >= 50) 

調用Update或事實修改將導致在他們的LHS一部分規則引用被再次觸發的規則。您有幾種選擇,如果這不是預期的行爲

1)不使用循環,這將防止在規則進行更新,觸發本身

2)使用更細粒度的事實。

3)更新後將麪包屑事實插入會話中,並檢查它們是否存在於LHS中。首先在你的模型中定義一個名爲Breadcrumb的事實類型,並有一個字符串屬性「name」,然後用作follws。

when 
    not Breadcrumb(name == "calculationXXXDone") 
    .... 
then 
    ... 
    //do some work 
    ... 
    bc = new Breadcrumb() 
    bc.name = "calculationXXXDone" 
    insert(bc) 
+0

alikox,在我發佈這個問題後,我不斷嘗試新的東西。我也嘗試使用修改和更新,因爲我知道如果你不使用MVEL風格,你需要告訴工作內存更新,但是我們可以使用avs.setAvailable(false); \t \t \t avs.setDiscountRateUnavailableMessage(「Unav Quanitity」); \t modify(avs); 和我得到 規則編譯錯誤:[規則名稱= '卷驗證'] \t COM /亞歷克斯/ qBPP /滴料/域/ Rule_Volume_Validation_0.java(13:639):該方法修改(AvailabilityStatusAndDiscountDisplay)是未定義的類型Rule_Volume_Validation_0 和update(avs)無限循環。 –

+0

@ alex-sundukovskiy我已經更新了答案。 –

+0

是的,謝謝,在你更新之前,我只是讓它工作在無迴路中。 我知道修改可能只在使用mvel時纔會使用。 我使用insert和no-loop = true來避免重新評估相同的規則。從文檔的HelloWorld例子中也可以看出。如果修改你不需要做無循環。 –