我是Drools的新手并且阅读了一些文档和教程,当然,我的问题有一个简单的解决方案。 我使用onle规则文件和类Counter,如下所示。环境是:Wintel JDK 1.7(71),DROOLS 6.1.0
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>
跑步的结果
Counter there (1) : 1
Counter there (2) : 1
Counters there (3) :
Counter there (1) : 2
Counter there (2) : 1
Counter there (2) : 2
Counters there (3) :
new Counter created
Counter there (1) : 3
Counter there (2) : 1
Counter there (2) : 2
Counter there (2) : 3
Counters there (3) :
retract counter with ID = 1
Counter there (2) : 2
Counter there (2) : 3
我的问题是:
程序代码不包含任何“kSession.delete”,所有事实都保存在工作内存中。因此,在我看来,每个fireAllRules调用后,应该为工作内存中的每个Counter对象触发规则“Counter shower 1”..“Counter shower 3”。一个用于STEP 1,两个用于STEP2,三个用于STEP3,例如但是输出列表只有“反向淋浴2”以这种方式工作。 “计数器淋浴1”和“计数器淋浴3”只能通过一次火灾一次性召唤。
为什么规则“反阵雨1”只能抓住最后插入的事实?那里有隐藏的行为吗?
3.为什么在使用count == 1收回对象计数器之后只有“Counter shower 2”会发生火灾?其他规则怎么样?
感谢您的帮助。
答案 0 :(得分:1)
问题1:程序代码不包含任何“kSession.delete”,所有事实都保存在工作内存中。因此,在我看来,规则&#34;反阵雨1&#34; ..&#34;柜台淋浴3&#34;应在每个fireAllRules调用后为工作内存中的每个Counter对象触发。一个用于STEP 1,两个用于STEP2,三个用于STEP3,例如但输出清单只有&#34;反击淋浴2&#34;以这种方式工作。 &#34;柜台淋浴1&#34;和#34;反向淋浴3&#34;只能通过一次fireAllRules召唤一次。
您应该了解fireAllRules
并未实际触发知识库中的所有规则。这个名字有点误导。 :)
而不是谈论规则&#34;解雇&#34;,对于他们而言,最好是激活&#34;激活&#34;。您有一个有状态会话,因此当您第一次调用fireAllRules
时,会根据您最初插入的Counter
激活三条规则。当您再次致电insert
/ fireAllRules
时,这些规则仍会针对初始Counter
激活!他们不需要再次激活。除非工作记忆的状态已经改变,导致规则停用并重新激活,否则你的右手边不会发现任何事情。
这实际上是有状态会话的重点。您的知识库可以逐步地学习&#34;事实并可以根据现有知识评估新事实。
从零知识假设中评估每一个事实是无状态会话的目的。
问题2:为什么要统治&#34;反击淋浴1&#34;只捕获最后插入的事实?
您有一个有状态会话,因此在第一个Counter
上激活fireAllRules
的初始插入匹配。从那以后,工作内存中没有任何变化影响初始激活,因此再次fireAllRules
时不再需要激活它。
问题3:为什么在收回对象计数器后只计数== 1&#34;计数器淋浴2&#34;火灾?其他规则怎么样?
&#34;反击淋浴2&#34;规则是受撤销影响的唯一规则,因为它有一个累加器来计算您的Counter
事实。
答案 1 :(得分:0)
这是一个关于所发生情况的逐个说明,注释显示在哪里可以找到Q1,Q2和Q3的答案。以&#39;!&#39;开头的行是您的Java或DRL代码中的语句,如执行,#&#39;#&#39;表示我的评论,并输出其他行。
! 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