Java 工作记忆&;Drools中的对象插入行为
我是Drools的新手,读过一些文档和教程,当然,我的问题有一个简单的解决方案。 我使用onle规则文件和类计数器,如下所示。环境是:WintelJDK1.7(71),DROOLS 6.1.0Java 工作记忆&;Drools中的对象插入行为,java,drools,business-rules,Java,Drools,Business Rules,我是Drools的新手,读过一些文档和教程,当然,我的问题有一个简单的解决方案。 我使用onle规则文件和类计数器,如下所示。环境是:WintelJDK1.7(71),DROOLS 6.1.0 public class DroolsInsertionTester { private Logger log = Logger.getLogger(this.getClass().getName()); private KieSession getNewStatefullKIESession (){
public class DroolsInsertionTester {
private Logger log = Logger.getLogger(this.getClass().getName());
private KieSession getNewStatefullKIESession (){
KieContainer kContainer = KieServices.Factory.get().getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("test");
return kSession;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
DroolsInsertionTester tester = new DroolsInsertionTester();
tester.test();
}
private void test() {
KieSession kSession = getNewStatefullKIESession();
Counter cnt1 = new Counter(1);
Counter cnt2 = new Counter(2);
FactHandle fact1, fact2;
// STEP 1
fact1 = kSession.insert(cnt1);
kSession.fireAllRules();
// STEP 2
fact2 = kSession.insert(cnt2);
kSession.fireAllRules();
}
public class Counter {
public int count;
public Counter (int cnt){
this.count = cnt;
}
有一条规则
rule "Counter shower 1"
when $Counter : Counter()
then
System.out.println("Counter there (1) : " + $Counter.count);
end
rule "Counter shower 2"
when
$Counter : Counter()
accumulate (Counter() ; $cnt : count())
then
System.out.println("Counter there (2) : " + $Counter.count);
end
rule "Counter shower 3"
when
Counter()
then
System.out.println("Counters there (3) : ");
end
rule "Counter creator"
when $Counter : Counter(count == 2)
then
insert (new Counter(3)); // STEP 3
System.out.println("new Counter created ");
end
rule "Counter remover"
when
$Counter : Counter(count == 1)
exists Counter (count == 3)
then
retract ($Counter) ; // STEP 4
System.out.println("retract counter with ID = 1");
end
这是kModule
<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="rules" packages="rules">
<ksession name="test" />
</kbase>
</kmodule>
我的问题是:
fireAllRules
实际上并不会触发知识库中的所有规则。这个名字有点误导人
与其说规则是“开火”,不如说规则是“激活”。您有一个有状态会话,因此当您第一次调用fireAllRules
时,您的三条规则将根据您最初插入的计数器激活。再次调用insert
/fireAllRules
时,初始计数器的这些规则仍处于激活状态!它们不需要再次激活。除非工作记忆的状态已经改变,导致一个规则被停用和重新激活,否则你将不会在你的右手边看到任何事情发生
这实际上是有状态会话的全部要点。您的知识库可以增量“学习”事实,并可以基于现有知识评估新事实
从零知识的假设中评估每个事实是无状态会话的目的
问题2:为什么规则“反淋浴1”只涉及最后插入的事实
您有一个有状态的会话,因此在第一个fireAllRules
上激活了计数器的初始插入匹配。此后,工作记忆中没有任何变化会影响初始激活,因此当您再次fireAllRules
时,它不再需要激活
问题3:为什么在count==1的retract object Counter(收回对象计数器)之后,只有“计数器淋浴2”触发?其他规则呢
“计数器淋浴2”规则是受收回影响的唯一规则,因为它有一个累加器来计算您的计数器事实。这里是一个关于发生了什么的详细说明,带有注释以显示在哪里可以找到Q1、Q2和Q3的答案。以“!”开头的行是Java或DRL代码中的语句,执行时,“#”表示我的注释,并输出其他行
! fact1 = kSession.insert(new Counter(1) );
# "Counter shower 1" matches; an activation binding $Counter to the inserted
# fact1 is created
# "Counter shower 2" matches; an activation binding $Counter to the inserted
# fact1 is created
# "Counter shower 3" matches; an activation with the inserted fact1
# is created
! kSession.fireAllRules();
# The Agenda contains three activations; the consequences of these rules are
# executed
Counter there (1) : 1
Counter there (2) : 1
Counters there (3)
! fact2 = kSession.insert(new Counter(2) );
# "Counter shower 1" matches; an activation binding $Counter to the inserted
# fact2 is created
# "Counter shower 2" matches; an activation binding $Counter to the inserted
# fact2 is created
# The accumulate changes as it now accumulates two Counter facts; therefore
# another activation is created with $Counter being bound to fact1, which
# is still (half-cocked) bound to this rule; the activation is completed due
# to the change in the accumulate.
# "Counter shower 3" matches; an activation with the inserted fact2
# is created
# Nothing has happened with fact1, so there is (by definition) no reason to
# recreate activations in relation to fact1. (Q1, Q2)
# With a Counter(2) present, also "Counter creator" is activated and put on
# the agenda.
! kSession.fireAllRules();
Counter there (1) : 2
Counter there (2) : 1
Counter there (2) : 2
Counters there (3)
new Counter created
! insert( new Counter(3) );
# "Counter shower 1" matches; an activation binding $Counter to the inserted
# fact3 is created
# "Counter shower 2" matches; an activation binding $Counter to the inserted
# fact3 is created
# The accumulate changes as it now accumulates three Counter facts; therefore
# another activation is created with $Counter being bound to fact1 and also
# to fact2, both of which are still (half-cocked) bound to this rule; the
# activation is completed due to the change in the accumulate. (Q3)
# "Counter shower 3" matches; an activation with the inserted fact2
# is created
# Nothing has happened with fact1 and fact3, so there is (by definition) no
# reason to recreate activations in relation to rules simply matching fact1
# and fact2. (Q1, Q2)
# With a Counter(1) and a Counter(3) present, "Counter remover" is activated
# and put on the agenda.
Counter there (1) : 3
Counter there (2) : 1
Counter there (2) : 2
Counter there (2) : 3
Counters there (3)
retract counter with ID = 1
# We have the three half-cocked activations of "Counter shower 2", where the
# set of accumulated Counter facts changed due to the retraction of
# Counter(1). The one with this Counter being bound to $Counter is a goner
# now, but the other two are reactivated with a shortened list of Counter
# facts to be counted.
Counter there (2) : 2
Counter there (2) : 3
嗨,劳恩,请看这个问题并帮我解决。
! fact1 = kSession.insert(new Counter(1) );
# "Counter shower 1" matches; an activation binding $Counter to the inserted
# fact1 is created
# "Counter shower 2" matches; an activation binding $Counter to the inserted
# fact1 is created
# "Counter shower 3" matches; an activation with the inserted fact1
# is created
! kSession.fireAllRules();
# The Agenda contains three activations; the consequences of these rules are
# executed
Counter there (1) : 1
Counter there (2) : 1
Counters there (3)
! fact2 = kSession.insert(new Counter(2) );
# "Counter shower 1" matches; an activation binding $Counter to the inserted
# fact2 is created
# "Counter shower 2" matches; an activation binding $Counter to the inserted
# fact2 is created
# The accumulate changes as it now accumulates two Counter facts; therefore
# another activation is created with $Counter being bound to fact1, which
# is still (half-cocked) bound to this rule; the activation is completed due
# to the change in the accumulate.
# "Counter shower 3" matches; an activation with the inserted fact2
# is created
# Nothing has happened with fact1, so there is (by definition) no reason to
# recreate activations in relation to fact1. (Q1, Q2)
# With a Counter(2) present, also "Counter creator" is activated and put on
# the agenda.
! kSession.fireAllRules();
Counter there (1) : 2
Counter there (2) : 1
Counter there (2) : 2
Counters there (3)
new Counter created
! insert( new Counter(3) );
# "Counter shower 1" matches; an activation binding $Counter to the inserted
# fact3 is created
# "Counter shower 2" matches; an activation binding $Counter to the inserted
# fact3 is created
# The accumulate changes as it now accumulates three Counter facts; therefore
# another activation is created with $Counter being bound to fact1 and also
# to fact2, both of which are still (half-cocked) bound to this rule; the
# activation is completed due to the change in the accumulate. (Q3)
# "Counter shower 3" matches; an activation with the inserted fact2
# is created
# Nothing has happened with fact1 and fact3, so there is (by definition) no
# reason to recreate activations in relation to rules simply matching fact1
# and fact2. (Q1, Q2)
# With a Counter(1) and a Counter(3) present, "Counter remover" is activated
# and put on the agenda.
Counter there (1) : 3
Counter there (2) : 1
Counter there (2) : 2
Counter there (2) : 3
Counters there (3)
retract counter with ID = 1
# We have the three half-cocked activations of "Counter shower 2", where the
# set of accumulated Counter facts changed due to the retraction of
# Counter(1). The one with this Counter being bound to $Counter is a goner
# now, but the other two are reactivated with a shortened list of Counter
# facts to be counted.
Counter there (2) : 2
Counter there (2) : 3