drools 7 规则引擎执行控制(Excution control)之规则冲突策略

1.概述

数据插入到工作内存(working memory)后,会触发所有规则的匹配,并执行完全匹配的规则。当数据完全匹配规则的时候,规则引擎会创建一个activation instance,并引用该rule和与之匹配的数据(也就是说多条数据与同一rule完全匹配时,会创建多个activation instance,这一点对于之后理解规则遍历集合很重要),然后添加到agenda中。Agenda根据冲突策略决定activation instance的执行顺序。

规则引擎分两个工作步骤:

- agenda evaluation: 收集所有可执行的rule 和数据并在agenda中注册activation instance,然后进入 working memory actions阶段,执行rule中的consequence语句(即then)。

- working memory actions: 执行注册在agenda中的activation,然后重新回到agenda evaluation阶段。

2.冲突解决策略

•salience

rule的属性之一,值为整型数值,支持正数或负数,默认值为0,用于设置规则执行的优先级,其值越大,优先级越高。

•agenda groups

可将一个或一个以上的rule设置为同一个agenda-group分组,默认分组为”MAIN”。只有获得焦点的分组才会被匹配执行,同一时间只有一个分组可以获得焦点,默认main分组持有焦点,可以使用auto-focus属性或者setFocus()方法将焦点分配给分组,auto-focus属性为true时会自动获取焦点,且优先级高于setFocus()方法(值为false时则不影响),当auto-focus属性为true 且setFocus()时,优先级高于仅auto-focus属性为true的分组;按setFocus()按倒序顺序,最后调用该方法的优先级较高;main分组最终会获得焦点;其他声明了agenda-group属性,但未分配焦点的不会发生规则匹配和执行(不完全匹配的规则不会执行then,但会执行when,这里未获得焦点,when都不会执行,这点对于规则性能方面的优化很重要)。

举例:

java代码:

KieServices ks = KieServices.Factory.get();
KieContainer kc = ks.getKieClasspathContainer();
KieSession kieSession = kc.newKieSession();
//获取agenda
Agenda agenda = kieSession.getAgenda();
//设置焦点,以下执行顺序为ag_2,ag_1,main
agenda.getAgendaGroup("ag_1").setFocus();
agenda.getAgendaGroup("ag_2").setFocus();
//移除main分组的焦点
//agenda.getAgendaGroup("MAIN").clear();
kieSession.fireAllRules();

drl文件:

//以下内容实际是遵循DRL语法写的,这里编辑设置为java只是为了好看。
//以下rules排版乱序,主要是为了排除rule位置顺序的干扰,顺序可以按照自己意愿排版。
function Boolean test(){
    //用于调试, rule when 中调用该function,打印信息,用于证明规则执行了匹配
    System.out.println("function excue");
    return true;
}
function Boolean test1(){
    //用于调试,rule when 中调用该function,打印信息,用于证明规则执行了匹配
    System.out.println("test1 excue");
    return false;
}

rule rule_4
agenda-group  "ag_4"
auto-focus true
  when
   // eval(test1())
    eval(test())
  then
      System.out.println("agenda-group_4 ");
end
rule rule_3
 when
    eval(true)
 then
     System.out.println("agenda-group_main");
end

rule rule_1
agenda-group "ag_1"
    when
        eval(true)
    then
 System.out.println("agenda-group_1");
 insert(true);
end
  rule rule_5
  agenda-group  "ag_2"
  //activation-group "acg_1"
  auto-focus

     when
        eval(true)
     then
         System.out.println("agenda-group_2_rule_5");
  end
 rule rule_2
 agenda-group  "ag_2"
 auto-focus
 //activation-group "acg_1"
 //salience 10
    when
       eval(true)
    then
        System.out.println("agenda-group_2");
 end

执行结果如下:

function excue
agenda-group_2_rule_5
agenda-group_2
agenda-group_4 
agenda-group_1
agenda-group_main

说明:以上执行结果中function excue排在最前边,是因为drools执行顺序是先运行所有rule的when,最后再按顺序执行then。

删除rule_4的 auto-focus 属性,由于未给rule_4分配焦点,所以rule_4未执行,运行结果如下:

agenda-group_2_rule_5
agenda-group_2
agenda-group_1
agenda-group_main

可以调用clear()方法在分组匹配执行前取消焦点,例如: agenda.getAgendaGroup("MAIN").clear();

•activation groups

可以将一个或多个rule设置为同一个activation-group分组,当分组中有全匹配的规则,则仅执行agenda中该分组中优先级最高的rule,其他都从agenda中移除。

上例中  rule_5 和 rule_2 增加属性activation-group "acg_1" ,rule_2增加属性 salience 10,rule_5和rule_2均为全匹配规则,由于在同一个activation-group 分组中,所以仅执行其中一个,因为rule_2的优先级更高,所以rule_2执行了,rule_5未被执行。运行结果如下:

agenda-group_2
agenda-group_1
agenda-group_main

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值