2016-07-04 37 views
0

存取在Drools中更新組成的對象時,我碰到一個特定的場景傳來:問題在Drools的

declare A 
    @propertyReactive 
    flag: Boolean 
end 

declare B 
    flag: Boolean 
end 

declare C 
    @propertyReactive 
    attrA: A 
    attrB: B 
end 

rule "Create A" 
    when 
     not A() 
    then 
     insert(new A()); 
     System.out.println("OBJECT A CREATED"); 
end 

rule "Create B" 
    when 
     not B() 
    then 
     insert(new B()); 
     System.out.println("OBJECT B CREATED"); 
end 

rule "Create C" 
    when 
     $A:A() 
     $B:B() 
     not C() 
    then 
     insert(new C($A,$B)); 
     System.out.println("OBJECT C CREATED"); 
end 

rule "Modify A" 
    when 
     $A:A(flag == false) 
     C() 
    then 
     modify($A) {setFlag(true)}; 
     String $output = "Now A is " + $A.getFlag(); 
     System.out.println($output); 
end 

rule "Print C when C is False" 
    when 
     C($A:attrA, attrA.flag == false, $B:attrB) 
    then 
     String $output = "A is " + $A.getFlag() + " and B is " + $B.getFlag(); 
     System.out.println($output); 
end 

rule "Print C when C is True" 
    when 
     C($A:attrA, attrA.flag == true, $B:attrB) 
    then 
     String $output = "A is " + $A.getFlag() + " and B is " + $B.getFlag(); 
     System.out.println($output); 
end 

rule "Print C when C is True 2" 
    when 
     C($A:attrA, $B:attrB) 
     A(this == $A, flag == true) 
    then 
     String $output = "2 A is " + $A.getFlag() + " and B is " + $B.getFlag(); 
     System.out.println($output); 
end 

輸出是:

OBJECT A CREATED 
OBJECT B CREATED 
OBJECT C CREATED 
A is false and B is false 
Now A is true 
2 A is true and B is false 

所以,我有以下問題:

  • 爲什麼規則「打印C當C爲真」不開火?
  • 爲什麼我需要將該規則重寫爲「打印C當C爲真2」才能使其工作?
  • 有沒有人對此有過解釋?

它看起來像Drools中有一些問題與嵌套類的存取工作...

非常感謝你。

回答

0

Drools僅對您的模式中使用的對象所做的更改發生反應,而不會響應它們可能包含的任何嵌套對象引用。這也不完全是真實的。

當您修改Drools(或其任何嵌套對象引用)中的事實時,您可以選擇讓Drools知道這個修改與否。就你而言,你永遠不會通知Drools他們。這就是爲什麼你的規則依賴於(不確定性)評估順序的原因。

如果您想讓Drools「知道」事實上的修改,那麼您必須在發生這些修改的規則的RHS中使用modifyupdate函數。

在您的具體情況中,您不僅嵌套對象,而且嵌套事實:AC。即使A是一個事實,在A(即使適當地通知Drools的)的修改將不會觸發模式的再評價是這樣的:

C(attrA.flag == true) 

的原因是因爲該圖案的類型是C而不是A。在這種情況下,像你的規則寫出的規則是更好的方法。

希望它有幫助,