Drools 混合XLS和DRL文件时,显著值nos是否正常工作?
我在DRL文本文件和XLS电子表格文件中定义了不同的规则。我的XLS规则是先执行的,我不明白为什么。示例是管理具有不同类别和答案的表单。答案有一个分数,用于向用户返回一些信息 我的第一条DRL规则是将一个类别中所有问题的所有分数相加:Drools 混合XLS和DRL文件时,显著值nos是否正常工作?,drools,Drools,我在DRL文本文件和XLS电子表格文件中定义了不同的规则。我的XLS规则是先执行的,我不明白为什么。示例是管理具有不同类别和答案的表单。答案有一个分数,用于向用户返回一些信息 我的第一条DRL规则是将一个类别中所有问题的所有分数相加: package Form; import ...; rule "Sum Category Score" salience 500 when $form : SubmittedForm(); $cat : CategoryWithScore(score == nu
package Form;
import ...;
rule "Sum Category Score"
salience 500
when
$form : SubmittedForm();
$cat : CategoryWithScore(score == null) from $form.categories;
$categoryScore : Number() from
accumulate($q : Question() from $cat.getQuestions(),
init( int $total = 0 ),
action( $total += $q.getAnswer().getScore(); ),
reverse( $total -= $q.getAnswer().getScore(); ),
result( $total )
);
then
$cat.setScore($categoryScore);
end
使用XLS文件,我根据总分定义类别的结果
我们可以看到,DRL文件具有salience 500
,XLS文件具有salience 250
。然后我希望首先执行DRL规则
如果我以规则格式打印XLS,一切似乎都是正确的:
package ScoreClassification;
//generated from Decision Table
import ...;
no-loop true
salience 250
// rule values at B13, header at B8
rule "Form Score Classification_13"
when
$form : SubmittedForm(); $cat : CategoryWithScore($cat.getText() == 'Cat1', $cat.getScore() >= 0, $cat.getScore() < 40) from $form.getCategoriesWithScore();
then
$cat.setResult('Good');
end
// rule values at B14, header at B8
...
包装分类;
//从决策表生成
进口。。。;
无循环为真
显著性250
//B13处的规则值,B8处的标题
规则“表格分数分类\u 13”
什么时候
$form:SubmittedForm()$cat:CategoryWithScore($cat.getText()=='Cat1',$cat.getScore()>=0,$cat.getScore()<40)来自$form.getCategoriesWithCore();
然后
$cat.setResult('Good');
结束
//B14处的规则值,B8处的标题
...
我在类别的方法getScore
和setScore
中放置了一些简单的System.out.println
,以查看发生了什么。我可以看到getScore
首先执行!(并具有空值)和更高版本的setScore
,正确分配值
为什么不尊重显著性?三件事
首先,您必须使用modify来改变工作记忆中的一个事实
rule "Sum Category Score"
...
then
modify( $cat ){ setScore( $categoryScore ) }
end
否则,规则评估将永远看不到更改的值
在OPs第一条评论后添加
第二,如果修改发生在事实集合中的对象中,并使用从中提取,则事情开始变得模糊。我避免这样做,并建议你也这样做。插入CategoryWithScore
facts,您的问题就解决了。(如果WM中同时存在多个表单,则您可能必须确定所选的类别whithscore
事实属于相同的提交表单
。)
第三,一个常见的误解是优先级(或显著性)会影响左侧评估的顺序,并可用于延迟规则的评估,其中约束表达式可能会遇到NPE。最好的做法是写入约束,使空值导致短路假
如果你认为这种混乱的规则:是的,你是对的。但是,当类成员被设置为一些默认值或带外值(在您的情况下可能是-1)而不是保留为null时,即使是纯Java代码也更健壮。谢谢您的评论。我使用了
update($form)
,但没有太多成功(同样的问题)。您的方法(最后是modify($form){setScore($cat,$categoryScore)}
因为$cat不在工作内存中)是正确的,但没有指出问题的解决方案(我非常感谢您的纠正)。使用空值作为分数的默认值的方法是因为一些规则没有分数(即写下你的名字),而其他一些问题可能会有负分数。然后我意识到显著性可能是我的解决方案。通过测试modify()
选项,我尝试了一个问题:org.drools.core.reteoo.rightuple.unlinkFromRightParent(rightuple.java:83)
(此处也有报道:)但这是另一个问题。嗯,必须滚动到最右边有它的缺点:-)期望WM中某个事实的某些子成分发生变化来触发重新评估是很棘手的,这就是为什么我总是建议不要太吝啬的w.r.t.插入。添加CategoryWithScore作为事实,将启动规则,但是,也没有什么可以确保在表单规则激活之前,类别将获得分配的分数。我可以在表单中添加一些额外的条件以确保订单,但这样做的目的是尽可能地简化XLS,因为可能会由非软件工程师的人员维护(此问题中的代码比原始代码简单)。在这种情况下,“显著性”几乎对任何人都是可以理解的,其他断言则更难理解。如果您的CategoryWithScore.score最初为-1,则在累积更改此字段之前,不会触发XLS规则。此行为仅在将XLS规则与DRL一起使用时显示。DRL和XLS中的显著性工作正常。只有当两者混合使用时,XLS规则才似乎不尊重DRL文件的显著性。