我对如何评估Drools决策表的条件有疑问。 我曾经以为条件是从左到右评估的,如果最左边的列检查给定的规则是错误的,它就不会检查剩余的条件。
这对我来说很重要的一个原因是将范围缩小到最左边的条件的概念。这意味着物体会更快地被踢出,而不是大多数物体首先满足广泛的条件,并继续检查其他条件。
然而,这不是我在单元测试中目睹的行为,我将在下面概述。
这个例子很简单,并不是为了证明范围的早期缩小。
|------------------|-------------------| |Condition |Condition | |------------------|-------------------| |myObject |myObject | |------------------|-------------------| |isNameEq("$param")|isValueEq("$param")| |------------------|-------------------| |A |1 | |A |2 | |A |3 | |A |4 | |A |5 | |B |4 | |B |5 | |B |6 | |B |7 | |------------------|-------------------|
在此示例中,isNameEq和isValueEq是java对象myObject中的函数。请忽略任何轻微的Drools错误/缺少声明的导入,因为我知道我的测试工作正常,这个插图是传达方案的近似值。
这两个函数包括一些简单的日志记录,以显示它们何时被调用。 对于name = A和value = 3的对象,我原本期望isValueEq函数永远不会被调用名称(最左侧)列中带有B的规则,因为该对象在这种情况下失败。
但是,日志记录表示按以下顺序进行函数调用:
这听起来不错吗?在我的假设中,我只是错了吗?这是rete算法和缓存评估(节点?)的一部分,因为它没有为(B,4),(B,5)调用isValueEq吗?
感谢任何能为我揭示这一点的人!
答案 0 :(得分:0)
电子表格的每一行都会转换为单个规则,例如第1行:
rule "whatever 1"
when
MyObject( isNameEq("A"), isValueEq("1") )
then
和另一个“A”和“2”,依此类推。每个插入的事实都是根据这些规则逐一评估的。
当函数隐藏对事实数据的访问时,算法(Rete或其他)的好处可能无法生效。您可以尝试简单约束(name ==“A”,value ==“1”)并通过对getter的修改来记录访问;这不会影响评估网络的构建方式。