5.5.3 “ eval ”
Eval is essentially a catch all which allows any semantic code (that returns a primitive boolean) to be executed. 在表达式中可以引用在 LHS 中出现的变量,和在 rule package 中的 Functions 。一个 Eval 应该是 LHS 中的最后一个 Conditional Element 。在一个 rule 中,你可以有多个 eval 。
Eval 不能被索引,因此不能像 Field Constraints 那样被优化。尽管如此,当 Functions 的返回值一直在变化时,应该使用 Eval ,因为这在 Field Constraints 中时不允许的。如果规则中的其他条件都匹配,一个 eval 每次都要被检查。(现在还不理解到底 eval 要怎么用?)
Example 5.16. eval
p2 : Parameter()
eval( p1.getList().containsKey(p2.getItem()) )
eval( isValid(p1, p2) ) // this is how you call a function in the LHS - a function called // "isValid"
5.5.4 “ not ”
“ not ”是一阶逻辑的存在量词( first order logic’s Existential Quantifier ) , 用来检查 WorkingMemory 中某对象的非存在性。现在,只有 Columns 可以放在 not 中,但是将来的版本会支持“ and ”和“ or ”。
Example 5.17. No Buses
Example 5.18. No red Buses
not ( Bus(color == " red " , number = = 42 ) ) // brackets are optional
5.5.5 “ exists ”
“ exists ” 是一阶逻辑的存在量词( first order logic’s Existential Quantifier ),用来检查 WorkingMemory 中某对象的存在性。可以将“ exists ”理解为“至少有一个”( at least one… )。它的意义不同于只有 Column 本身,“ Column ”本身可以理解为“对于每一个 … ”( for each of … )。如果你对一个 Column 使用了“ exists ”,那么规则将只 activate 一次,而不管 WorkingMeomry 中有多少个数据匹配了那个条件。
现在,只有 Columns 可以放在“ exists ”中,但是将来的版本会支持“ and ”和“ or ”。
Example 5.19. At least one Bus
Example 5.20. At least one red Bus
5.5.6 “ group ”
Group 的作用相当于代数学中的“()”,显式的指明操作的顺序。
5.6 再谈自动装箱和原始类型
Java 5 支持在原始类型与其对应包装类之间的装拆箱。尽管如此,因为要让 drools 能够在 J2SE 1.4 下运行,我们不能依靠 J2SE 。因此, drools 自己实现了自动装箱。被引用(即被 Bound Variable 绑定)的 Field 将被自动进行装箱(如果它们本身就是 object ,就不会有任何变化)。尽管如此,必须要注意的是,他们并不会被自动拆箱。
还有一点要注意的,就是对于 ReturnValue Constraints ,返回值的代码必须返回一个对象,而不能是一个原始类型。
6 . Query
一个 query 只包含了一个 rule 的 LHS 结构(你不用指定“ when ”或“ then ”)。这是查询 WorkingMemory 中匹配条件的 Facts 的简单的方法。
要得到结果,要使用 WorkingMemory.getQueryResults(“name”) 方法,其中“ name ”就是 query 的名字。 Query 的名字在 RuleBase 中是全局的,所以, do not add queries of the same name to different packages for the same RuleBase 。
下面的例子创建了一个简单的 query 来查询所有年龄大于 30 的人:
Example 6.1. Query People over the age of 30
person : Person( age > 30 )
end
我们通过一个标准的循环来迭代一个返回的 QueryResults 对象。每一次的 iterate 将返回一个 QueryResult 对象。我们可以用 QueryResult 对象的 get() 方法来访问每个 Column ,通过传入 Bound Declaration 或 index position 。
Example 6.2. Query People over the age of 30
System.out.println( " we have " + results.size() + " people over the age of 30 " );
System.out.println( " These people are are over 30: " );
for ( Iterator it = results.iterator; it.hasNext(); ) {
QueryResult result = ( QueryResult ) it.next();
Person person = ( Person ) result.get( " person " );
System.out.println( person.getName() + " \n " );
}