在drools中理解议程小组

时间:2011-07-29 07:58:11

标签: drools

我尝试了一个示例,看看议程小组是如何运作的。最初,我将ksession的重点放在议程组“ag1”上并解除了规则。

package com.sample

import com.sample.DroolsTest.Message;

rule "Hello World"
  agenda-group "ag1"
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println( "Hello World" ); 
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

rule "Hello World 2"
  agenda-group "ag2"
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println( "Hello World 2" ); 
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

rule "GoodBye"
  agenda-group "ag1"
    when
        m : Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( "GoodBye" );
        drools.setFocus("ag2");
        System.out.println("comeon man");
        m.setStatus(com.sample.DroolsTest.Message.HELLO);
        update(m);
end

rule "GoodBye 2"
  agenda-group "ag2"
    when
        Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( "GoodBye 2" );
end

这是我得到的输出。

Hello World
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
...
...

我能理解输出的前5行直到“GoodBye 2”。但由于焦点被设定为“ag2”,它是如何回到“ag1”议程组的“GoodBye”规则并因此再次出现。

感谢。

2 个答案:

答案 0 :(得分:23)

议程小组像堆栈一样工作。将焦点设置为给定议程组时,该组将置于堆栈顶部。当引擎尝试触发下一次激活并且给定组中没有更多激活时,该组将从堆栈顶部移除,并且其下方的组再次获得焦点。

所以它是这样的(main是始终存在的默认组):

* STACK: [MAIN, ag1]

Hello Word fires and activates both "GoodBye" rules
GoodBye fires, activates both "Hello World" rules and sets the focus to "ag2"

* STACK: [MAIN, ag1, ag2]

Hellow World 2 fires, cancels the "Hello World 1" rule and activates both "GoodBye" rules
GoodBye 2 fires because ag2 has the focus

* There are no more activations in ag2 to fire, so ag2 is removed from the stack
* STACK: [MAIN, ag1]
* The "GoodBye" rule is still active in ag1, so it fires

GoodBye fires, activates both "Hello World" rules and sets the focus to "ag2"

* STACK: [MAIN, ag1, ag2]

Hellow World 2 fires, cancels the "Hello World 1" rule and activates both "GoodBye" rules
...

循环重复。

如果您在Eclipse IDE中使用审核日志,则很容易看到这种行为。

希望这有帮助。

答案 1 :(得分:1)

由于您在计算规则期间更改了会话中的事实(您的Message对象在您的事实中),因此再次计算其他规则,而不是取决于它们所属的议程组,以便更新流口水知识库。

您可以在no-loop true定义

之后添加rule以防止这种情况发生

我不太确定,但这是我在我的应用上发现的行为,应该如此解决你的无限循环。顺便说一下,当事实发生变化时再次计算规则似乎是合乎逻辑的。