当前位置: 首页 > 知识库问答 >
问题:

工作记忆

海新霁
2023-03-14

A我是Drools的新手,读过一些文档和教程,当然,我的问题有一个简单的解决方案。我使用onle规则文件和类计数器,如下所示。环境为: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

我的问题是:

>

为什么“反淋浴1”规则只涉及最后插入的事实?是否存在任何隐藏行为?

3、为什么在count==1的retract object Counter(收回对象计数器)后,仅“Counter shower 2”(计数器淋浴器2)发生火灾?其他规则呢?

谢谢你的帮助。

共有2个答案

郭炳
2023-03-14

下面是对发生的事情的详细描述,带有注释以显示在哪里可以找到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
戚俊人
2023-03-14

问题1:程序代码不包含任何“kSession.delete”,所有事实都保存在工作内存中。所以,在我看来,规则是“反淋浴1”。。在每次fireAllRules调用后,应为工作内存中的每个计数器对象触发“Counter shower 3”。一次用于步骤1,两次用于步骤2,三次用于步骤3,例如,但输出列表说明只有“计数器淋浴器2”以这种方式工作。“Counter shower 1”和“Counter shower 3”仅在一次fireAllRules调用中触发一次。

您应该了解,fireAllRules实际上并不会触发知识库中的所有规则。这个名字有点误导人。:)

与其说规则是“开火”,不如说规则是“激活”。您有一个有状态的会话,因此当您第一次调用fireAllRules时,其中三个规则将根据您最初插入的计数器激活。再次调用“插入”时,初始计数器的规则仍会激活!它们不需要再次激活。除非工作记忆的状态已经改变,导致一条规则被停用和重新激活,否则你不会在你的右手边看到任何事情发生。

这实际上是有状态会话的全部要点。您的知识库可以增量地“学习”事实,并且可以根据现有知识评估新事实。

无状态会话的目的是从零知识的假设中评估每个事实。

问题2:为什么规则“柜台淋浴1”只抓住最后插入的事实?

您有一个有状态会话,因此在第一个fireAllRules上激活了与初始插入计数器的匹配。此后,工作记忆中没有任何变化会影响初始激活,因此当您再次激活fireAllRules时,它不再需要激活。

问题3:为什么在count==1的retract object Counter(收回对象计数器)之后,仅“Counter shower 2”(计数器淋浴2)会触发?其他规则呢?

“计数器淋浴2”规则是唯一受收回影响的规则,因为它有一个累加器计算您的计数器事实。

 类似资料:
  • 问题内容: 关闭。 这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为Stack Overflow的主题。 8年前关闭。 改善这个问题 我在使用MySQL的数据库上执行SQL查询,但仅从预期的24000行中获取了前1000行。如果将结果导出到XML表单,我将再次获得前1000个。有没有办法禁用该限制并取回所有行?否则,我将不得不合并24个XML文件:/ 问题答案: 请执行

  • 7.21测评:性格测试 7.23一面: 自我介绍 讲讲第一个项目及遇到最大的挑战 为什么来合肥 对38所了解吗 怎么不投南京研究所 反问问题 7.28二面: 自我介绍 是否保研 代码能力强吗?用什么语言写的? 发表的文章是根据项目来的吗? 深挖第一个项目 你的执行力如何? 社团具体的经历,你做了什么? 有没有期望的城市或者工作?南京的研究所投了吗? 有兄弟姐妹吗?有男朋友吗? 了解过38所吗? 对

  • 我有一个maven项目,它使用log4j2进行日志记录。我想覆盖RootLogger的模式。 这是我的log4j2。属性文件: 这是我的pom。log4j的xml文件: 我这样叫我的记录仪: 我的配置有两个问题。第一个是根记录器不使用我的ConsolePender(警告等以默认格式显示),在记录错误时,我只得到第一行,而不是整个堆栈跟踪)。

  • 我有以下Spring Security配置: 我想让每个人(包括经过身份验证的用户和未经身份验证的用户)都可以访问特定的页面(比如索引页面(“/”),但同时,能够根据用户是否经过身份验证以及其角色来管理应该在jsp中看到哪些部分。 我的jsp部分如下所示: 所有的认证机制都可以正常工作。问题是,即使我使用“管理员”角色登录,链接也永远不会显示。 我尝试调试我的userdetails服务实现,并验证

  • 互联网上有许多帖子建议如何从logback迁移到log4j2进行Spring引导日志记录。 参考这个sof post-Spring Boot日志与log4j2-我已经配置我的项目使用log4j2。然后我添加了一些基本的log4j2.xml和log4j2.properties文件来测试。 但是在这些更改之后,我的项目无法进行任何日志记录。有人能帮我找出毛病吗? 项目代码可在github-https:

  • 因此,我在Django中有我的views.py,它将对象列表呈现给我的html模板。一切正常。现在,这些对象有一些与之关联的对象ID。我将“static/images/”目录中的图像命名为与对象ID相同的名称。 因此,图像1.jpg将对应于对象id=1的对象,2.jpg对象id=2,依此类推。 现在我想在html中加载img标记中的图像,但是img标记的src URL将取决于对象id。 以下是我的