Drools

时间:2016-07-04 16:26:54

标签: class nested drools composite accessor

在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为真2时打印C ”以使其有效?
  • 有人对此有解释吗?

看起来Drools在使用嵌套类的访问器方面存在问题......

非常感谢。

1 个答案:

答案 0 :(得分:0)

Drools仅对模式中使用的对象执行的更改做出反应,而不对它们可能包含的任何嵌套对象引用做出反应。这也不完全正确。

当您在Drools(或其任何嵌套对象引用)中修改事实时,您可以选择让Drools知道此修改。在你的情况下,你永远不会通知Drools他们。这就是为什么你的规则依赖于(非确定性)评估顺序的原因。

如果你想让Drools"知道"关于对事实的修改,那么您必须在发生这些修改的规则的RHS中使用modifyupdate函数。

在您的特定情况下,您不仅拥有嵌套对象,还拥有嵌套事实:AC。即使A是事实,A上的更改(即使已正确通知Drools)也不会触发重新评估此类模式:

C(attrA.flag == true)

原因是因为模式的类型是C而不是A。在这种情况下,像Print C when C is True 2规则一样编写的规则是更好的方法。

希望它有所帮助,