rule "no CEs"
when
// empty
then
... // actions (executed once)
end
// 上面的rule可以用下面的写法代替:
rule "eval(true)"
when
eval( true )
then
... // actions (executed once)
end
1.隐含的and
rule "2 unconnected patterns"
when
Pattern1()
Pattern2()
then
... // actions
end
// The above rule is internally rewritten as:
rule "2 and connected patterns"
when
Pattern1()
and Pattern2()
then
... // actions
end
Person( age == 50 )
// this is the same as:
Person( getAge() == 50 )
这两个匹配看以来是一致的,当时getAge()的底层实现我们是看不到的。如果在其内部对age进行了一系列修改可能会导致我们的误判。例如:
public int getAge() {
age++; // Do NOT do this
return age;
}
public int getAge() {
Date now = DateUtil.now(); // Do NOT do this
return DateUtil.differenceInYears(now, birthday);
}
3.2 支持嵌套的表达式
Person( address.houseNumber == 50 )
// this is the same as:
Person( getAddress().getHouseNumber() == 50 )
Person( incrementAndGetAge() == 10 ) // Do NOT do this
3.5 事实的状态不应在规则调用之间发生变化(除非这些事实在每次更改时都标记为更新到工作内存):
Person( System.currentTimeMillis() % 1000 == 0 ) // Do NOT do this
3.6 当约束中的值属性不匹配时将会抛出异常。
//throw "10" would coerce to a numeric 10.
Person( age == "10" )
3.7 ","分割代替and
// Person is at least 50 and weighs at least 80 kg
Person( age > 50, weight > 80 )
// Person is at least 50, weighs at least 80 kg and is taller than 2 meter.
Person( age > 50, weight > 80, height > 2 )
Person( ( age > 50, weight > 80 ) || height > 2 ) // Do NOT do this: compile error
// Use this instead
Person( ( age > 50 && weight > 80 ) || height > 2 )
3.9 绑定变量
可以将属性定义给一个变量
// 2 persons of the same age
Person( $firstAge : age ) // binding
Person( age == $firstAge ) // constraint expression
前缀美元符号($)只是一个约定; 它可以在复杂的规则中使用,它有助于轻松区分变量和字段。
出于向后兼容性原因,允许(但不建议)混合约束绑定和约束表达式,如下所示:
// Not recommended
Person( $age : age * 2 < 100 )
// Recommended (separates bindings and constraint expressions)
Person( age * 2 < 100, $age : age )
// Same as childList(0).getAge() == 18
Person( childList[0].age == 18 )
// Same as credentialMap.get("jsmith").isValid()
Person( credentialMap["jsmith"].valid )
此注释适用于DRL类型声明:
declare Person
@classReactive
firstName : String
lastName : String
end
以及Java类:
@ClassReactive
public static class Person {
private String firstName;
private String lastName;
}
例如,通过使用此功能,如果您有如下规则:
rule "Every person named Mario is a male"
when
$person : Person( firstName == "Mario" )
then
modify ( $person ) { setMale( true ) }
end
// listens for changes on both firstName (inferred) and lastName
Person( firstName == $expectedFirstName ) @watch( lastName )
// listens for all the properties of the Person bean
Person( firstName == $expectedFirstName ) @watch( * )
// listens for changes on lastName and explicitly exclude firstName
Person( firstName == $expectedFirstName ) @watch( lastName, !firstName )
// listens for changes on all the properties except the age one
Person( firstName == $expectedFirstName ) @watch( *, !age )
- DISABLED => 此功能已关闭,所有其他相关注释都将被忽略
- ALLOWED =>类型不是属性反应型,除非它们没有用@PropertyReactive(@ClassReactive的对偶)注释
types are not property reactive unless they are not annotated with @PropertyReactive (which is the dual of @ClassReactive)
- ALWAYS => 所有类型都是属性相关的. 这是默认的。
pensioner : ( Person( sex == "f", age > 60 ) or Person( sex == "m", age > 65 ) )
(or pensioner : Person( sex == "f", age > 60 )
pensioner : Person( sex == "m", age > 65 ) )
由于条件元素or导致多个子规则生成,每个可能的逻辑结果一个,上面的示例将导致内部生成两个规则。这两个规则在工作记忆中独立工作,这意味着两者都可以match, activate and fire - 没有捷径。
// Brackets are optional:
not Bus(color == "red")
// Brackets are optional:
not ( Bus(color == "red", number == 42) )
// "not" with nested infix and - two patterns,
// brackets are requires:
not ( Bus(color == "red") and
Bus(color == "blue") )
exists Bus(color == "red")
// brackets are optional:
exists ( Bus(color == "red", number == 42) )
// "exists" with nested infix and,
// brackets are required:
exists ( Bus(color == "red") and
Bus(color == "blue") )
7 高级条件元素
7.1 条件元素forall
条件元素forall完成了Drools中的First Order Logic支持。forall当与第一个约束匹配的所有事实与所有剩余模式匹配时,条件元素的计算结果为true。例:
rule "All English buses are red"
when
forall( $bus : Bus( type == 'english')
Bus( this == $bus, color = 'red' ) )
then
// all English buses are red
end
rule "All Buses are Red"
when
forall( Bus( color == 'red' ) )
then
// all Bus facts are red
end
另一个例子显示了内部的多个模式forall:
rule "all employees have health and dental care programs"
when
forall( $emp : Employee()
HealthCare( employee == $emp )
DentalCare( employee == $emp )
)
then
// all employees have health and dental care
end
rule "not all employees have health and dental care"
when
not ( forall( $emp : Employee()
HealthCare( employee == $emp )
DentalCare( employee == $emp ) )
)
then
// not all employees have health and dental care
end
rule "apply 10% discount to all items over US$ 100,00 in an order"
when
$order : Order()
$item : OrderItem( value > 100 ) from $order.items
then
// apply discount to $item
end
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$p : Person( )
$a : Address( state == "NC") from $p.address
then
modify ($p) {} // Assign person to sales region 1 in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person( )
$a : Address( city == "Raleigh") from $p.address
then
modify ($p) {} // Apply discount to person in a modify block
end
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$p : Person(address.state == "NC" )
then
modify ($p) {} // Assign person to sales region 1 in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person(address.city == "Raleigh" )
then
modify ($p) {} //Apply discount to person in a modify block
end
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$p : Person($addresses : addresses)
exists (Address(state == "NC") from $addresses)
then
modify ($p) {} // Assign person to sales region 1 in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person($addresses : addresses)
exists (Address(city == "Raleigh") from $addresses)
then
modify ($p) {} // Apply discount to person in a modify block
end
但是,以下略有不同的方法确实表现出问题:
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$assessment : Assessment()
$p : Person()
$addresses : List() from $p.addresses
exists (Address( state == "NC") from $addresses)
then
modify ($assessment) {} // Modify assessment in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$assessment : Assessment()
$p : Person()
$addresses : List() from $p.addresses
exists (Address( city == "Raleigh") from $addresses)
then
modify ($assessment) {} // Modify assessment in a modify block
end
rule R when
$l : List( )
(String() from $l)
(String() or Number())
then end
7.3 条件元素collect
条件元素collect允许规则对从给定源或working memory获得的对象集合进行推理。在First Oder Logic术语中,这是基数量词。一个简单的例子:
import java.util.ArrayList
rule "Raise priority if system has more than 3 pending alarms"
when
$system : System()
$alarms : ArrayList( size >= 3 )
from collect( Alarm( system == $system, status == 'pending' ) )
then
// Raise priority, because system $system has
// 3 or more alarms pending. The pending alarms
// are $alarms.
end
import java.util.LinkedList;
rule "Send a message to all mothers"
when
$town : Town( name == 'Paris' )
$mothers : LinkedList()
from collect( Person( gender == 'F', children > 0 )
from $town.getPeople()
)
then
// send a message to all mothers
end
import accumulate some.package.VarianceFunction variance
rule "Calculate Variance"
when
accumulate( Test( $s : score ), $v : variance( $s ) )
then
// the variance of the test scores is $v
end
rule "Apply 10% discount to orders over US$ 100,00"
when
$order : Order()
$total : Number( doubleValue > 100 )
from accumulate( OrderItem( order == $order, $value : value ),
sum( $value ) )
then
// apply discount to $order
end
rule "Apply 10% discount to orders over US$ 100,00"
when
$order : Order()
$total : Number( doubleValue > 100 )
from accumulate( OrderItem( order == $order, $value : value ),
init( double total = 0; ),
action( total += $value; ),
reverse( total -= $value; ),
result( total ) )
then
// apply discount to $order
end
原题链接:#137 Single Number II
要求:
给定一个整型数组,其中除了一个元素之外,每个元素都出现三次。找出这个元素
注意:算法的时间复杂度应为O(n),最好不使用额外的内存空间
难度:中等
分析:
与#136类似,都是考察位运算。不过出现两次的可以使用异或运算的特性 n XOR n = 0, n XOR 0 = n,即某一
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, det