Drools 混合XLS和DRL文件时,显著值nos是否正常工作?

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

我在DRL文本文件和XLS电子表格文件中定义了不同的规则。我的XLS规则是先执行的,我不明白为什么。示例是管理具有不同类别和答案的表单。答案有一个分数,用于向用户返回一些信息

我的第一条DRL规则是将一个类别中所有问题的所有分数相加:

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文件的显著性。