首页 > 其他分享 >drools_12_lhs

drools_12_lhs

时间:2022-11-01 13:31:55浏览次数:78  
标签:drools 12 示例 pattern age when Order lhs order

LHS (left hand side) 部分

Drools 作为规则引擎, 最重要的功能就是完成 pattern match, 即按照 LHS 对工作内存的fact进行匹配, 老版Drools使用的匹配算法是RETE(读音[reetee]), 该算法的核心策略是分而治之+以空间换时间, 基于该算法, 即使是有大量的rule和fact需要匹配, 规则执行的时间复杂度也是可以接受的, 当然内存占用会比较高.

完整的 LHS 语法比较复杂, 可参考​​Drools Documentation​​ 但基本语法是非常简单, 一般情况下只需要基本语法就足够了.

绑定变量

下面就是一个常用的LHS, 包含两个关联对象的匹配, 定义了两个对象级别绑定变量, 一个属性级的绑定变量.

when
$customer:Customer(age>20 && location=="China" && gender=="male", $age:age)
$order: Order(customer==$customer, price>1000)
then
...

约束中的操作符:

约束中常用的操作符号有:

  • < 和 <= 和 > 和 >= 符号, 这些与java含义一致, 可以对数值和字符串进行对比
  • == , 这个是null安全的equal, 和java的 == 含义不同.
  • !=, 这个是null安全的不等于符号, 和java中的 != 含义不同
  • contains , 包含, 可以判断字符串包含子串, 也可以判断集合/数组包含元素
  • not contains, 不包含
  • memberOf, 属于, 注意 ​​Of​​ 要大写. 和 contains 语义正好相反.
  • not memberOf, 不属于,注意 ​​Of​​ 要大写.
  • matches, 正则匹配
  • not matches, 正则不匹配
  • instanceOf, 类型属于
  • not instanceOf, 类型不属于
  • in , 这个作用和 memberOf 类似, 写法同SQL的in子句
  • not in, 这个和 not memberOf 类似, 写法同SQL的 not in 子句
  • && ,逻辑与, 和java的含义
  • || , 逻辑或, 和java的含义

逗号分隔符

逗号分隔符可以分隔两个条件, 其作用等同于 &&, 但优先级比较 && 和 || 要低, 一般情况下, 推荐使用逗号分隔符因为其可读性更好.

字符串专用运算符 str

$order:Order(name str[startsWith] "A")
$order:Order(name str[endsWith] "A")
$order:Order(name str[length] 15)

分组条件元素(conditional element)

分组条件元素不同于普通的操作符, 普通操作符用在field上, 而, 分组条件元素被用于​​pattern​​之上.

  • and
    and 分组条件元素的作用是​​​logic join​​, 连接两个pattern, 要求同时满足两个pattern, 一般我们会省略这里的 and 关键词.
when
Cheese(type=="IceCream", $cheeseType:type)
and //这里的and可以被省略
Person(favoriteCheese==$cheeseType)
then
...
  • or
    or 分组条件元素的作用是​​​logic split​​, 连接两个pattern, 形成逻辑或的关系, 在真实项目中, logic split推荐写成两个规则, 而不是使用 or 分组写到一个规则中.
rule "infixAnd"
when
( $c1 : Customer ( country=="GB") and PrivateAccount(owner==$c1))
or
( $c1 : Customer (country=="US") and PrivateAccount(owner==$c1))
then
showResult.showText("Person lives in GB or US");
end
  • exists
    exists 是一元分组元素, 用于working memory是否存在符合pattern的fact. 如果有多个fact对象符合pattern, exists 也仅仅会触发一次.
when 
//触发一次
exists Order(qty>1000)
then
...
when 
//触发多个
Order(qty>1000)
then
...
  • not
    not 也是一元分组元素, 用于检查是否​​不​​存在fact符合pattern, 含义正好和 exists 相反.
  • from
    前面类型匹配的对象都是存在于工作内存中, 但有时候我们需要对非工作内存的对象进行模式匹配, 比如是在global变量中, 比如是在fact的某个属性中, drools 提供了from子句可以支持从这些非工作内存中进行匹配.
    下面示例的 $orderItem 就是从 $order.items 中进行模式匹配.
    效果: 如果只有一个order对象,其他 items 有两个子项, 控制台会输出两行内容.
package com.sample.rules

import com.sample.Order;
import com.sample.OrderItem;

rule "test"
when
$order:Order()
$orderItem:OrderItem(name =="book") from $order.items
then
System.out.println($orderItem);
end
  • from collect
    上面的from 示例, 最终派生的变量 $orderItem 是单独的对象, 有时候我们需要将派生的变量形成一个集合, 这时就可使用from collect语法.
    下面示例是, 匹配除所有 orderItem 数量>=2 的 order.
    效果:如果只有一个order对象,其他 items 有两个子项, 控制台会输出一行内容
package com.sample.rules

import com.sample.Order;
import com.sample.OrderItem;
import java.util.List;

rule "test"
when
$order:Order()
$items: List(size>=2) from collect (OrderItem() from $order.items)
then
System.out.println($items.size());
end
  • forall forall 一般作用于2个或多个pattern, 含义是对于符合pattern1的fact, 要求也必须符合后续其他pattern, 只有这样forall的结果才为true, forall 就是一个加强版的 exists. 语法:
forall(

pattern1

pattern2

pattern3

)

  • 示例:
rule "test"
when
forall(
$order:Order(qty>10)
OrderItem(order== $order && batchMode=="T" )
)
then
//$order 变量只能用在forall的后续pattern中, RHS 将无法使用该变量.
System.out.println("all order qty>10 is in batch mode");
end
  • accumulate
    有时候我们需要对fact先做一些累计统计, 然后基于累计值进行模式匹配, 这时就需用 accumulate 分组元素.
    例子: 需要对最低温度<20并且平均温度>70的sensor reading进行报警处理, 显然这需要先进行 accumulate,
    语法:
accumulate(
<source pattern>;
<functions> [;<constraints>]
)

示例:

rule "Raise alarm"
when
$s : Sensor()
accumulate( Reading( sensor == $s, $temp : temperature );
$min : min( $temp ),
$max : max( $temp ),
$avg : average( $temp );
$min < 20, $avg > 70 )
then
// Raise the alarm.
end

LHS 访问对象属性的方法

LHS访问对象属性可以使用field 名称也可以使用getter方法, 但更推荐直接使用field, 因为它可以利用上 drools 的field indexing, 有更好的性能.

Person(age>18)  //age 属性
Person(address.houseNumber==50) //访问address子对象的属性

list 和 map 的访问

可以通过下标访问数组/list元素, 可以通过key访问map.
list示例: ​​​ Person(childList[0].age==18) ​​​ list示例: ​​ Person(childMap["Allen"]) ​

规则的继承

新规则继承一个老规则, 继承的仅仅是老规则的LHS部分. 规则继承主要使用场景有: 强化原规则, 或者组合两个规则.

  • 强化规则的示例:
rule "rule1" 
when Student(age>10)
then
System.out.print("rule1 fired");
end

rule "rule2" extends "rule1"
when Student(age<20)
then
System.out.print("rule2 fired");
end
  • 组合两规则的示例
rule "rule3" 
when
$student:Student(age>10)
then
System.out.print("rule3 fired");
end

rule "rule4" extends "rule3"
when
$score:Score(student==$student)
then
System.out.print("rule4 fired");
end

参考

​Drools规则描述语言快速手册​



标签:drools,12,示例,pattern,age,when,Order,lhs,order
From: https://blog.51cto.com/u_15585381/5813402

相关文章

  • git checkout命令详解 git checkout feature/test123
    gitcheckout命令详解gitcheckoutfeature/test123//切换到feature/test123分支保证当前分支没有修改提交,否则回提示error:Yourlocalchangestothefollowing......
  • [LeetCode] 1293. Shortest Path in a Grid with Obstacles Elimination
    Youaregivenan mxn integermatrix grid whereeachcelliseither 0 (empty)or 1 (obstacle).Youcanmoveup,down,left,orrightfromandtoanem......
  • ANT+ 自行车车灯 数据页18页-主光的频道ID(0x12)
    数据页18应在ANT+控制器的请求下发送,并且可以选择性地包括在连接状态下作为从ANT+自行车灯广播的主要数据页之一。这个数据页允许控制器发现并连接到已经存在的网络,如5.2.2.......
  • uva 12563 Jin Ge Jin Qu hao
    01背包,这题设计状态f[i][j]为刚好用完时间j时的歌曲数,这样方便找到用时(初始化设置一下就好 #include<iostream>#include<algorithm>#include<cstring>usingna......
  • 【CF1292F】Nora's Toy Boxes(状压DP)
    考虑将点分为$A,B$两类。其中$[x\inA]\iff\exists_{y\neqx},y|x$。那么我们删去的点只可能在$B$类中,且当前$x\inB$可删当且仅当存在$y\inB,z\inA$使得$z|x......
  • Java 从入门到放弃12 - 《网络编程基础》
    网络编程基础为了把计算机接入互联网,就必须要使用TCP/IP协议。TCP/IP协议泛指互联网协议,其中最重要的两个就是TCP和IP协议,而使用其他网络协议都是无法接入互联网的IP地......
  • 单片机 N76E003 EC12 编码器
    sbitEC_B=P0^0;//编码器P0.0端口sbitEC_A=P1^3;//编码器P1.3端口staticuint8_tEC_A_Val=0,EC_B_Val=0;staticuint8_tEC_A_old=0,EC_B_ol......
  • 12.整合Mybatis
    12.整合Mybatis12.1.步骤:1.导入相关jar包junitmybatismysql数据库spring相关的aop织入mybatis-spring【new】2.编写配置文件3.测试12.2.回忆Mybatis编写实......
  • 使用int128记录大整数
    部分编译器支持128bit的整数表示,但是需要手写输入输出。注意:__int128等价于__int128_t,不存在int128和int128_t。输出函数:voidPrint128(__int128num){if(num<0......
  • 【性能测试】Loadrunner12.55(二)-飞机订票系统-脚本录制
    1.1飞机订票系统Loadrunner12.55不会自动安装飞机订票系统,要自己手动安装。我们需要下载WebTools以及一个小插件strawberryhttps://marketplace.microfocus.com/appd......