如何在Drools中控制规则评估(或规则执行)阶段? [英] How to control rule evaluation (or rule execution) stages in Drools?

查看:132
本文介绍了如何在Drools中控制规则评估(或规则执行)阶段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道Drools中的显着性在规则执行顺序下提供控制。但是上面是当显着性无法解决我遇到的问题的一个例子。

I know that "salience" in Drools provides control under rule execution sequence. But above is an example of the problem when "saliences" cannot help anymore that I've faced with.

在这里,我有三个规则被依次执行:

Here I have three rules being executed one after another:

rule "Rule 1"
salience 30
when

then
    Resource resource1 = new Resource();
    resource1.setName("Resource 1");
    resource1.setAmount("5");
    insert(resource1);
    System.out.println("First");
end

rule "Rule 2"
salience 20
//no-loop (interesting, it doesn't lead to a loop)
when
    $resource1: Resource(name == "Resource 1")
then
    modify($resource1) {setAmount("20")};
    System.out.println("Second");
end

rule "Rule 3"
salience 10
when
    $resource1: Resource(name == "Resource 1", 
    Double.parseDouble(amount) > 10)
then
    System.out.println("Rule is fired");
end

我希望第三条规则被触发,并且有一个 Rule is fired行在控制台中,但未执行。

据我所知,问题在于规则评估阶段,即在执行之前一次性评估所有三个规则,然后才根据它们的显着性轮执行。

并且在评估时 $ resource1.amount 5 ,这就是为什么不触发第三条规则的原因。如果您在第一个规则中输入的数字大于 10 ,则3d规则将触发。如果根本不设置金额,则会导致异常。

如何解决此问题,以便触发3d规则?

I expected the third rule is fired and there's a "Rule is fired" line in the console, but it is not executed.
As I understand the issue is with rules evaluation stage when all three rules are evaluated at once before execution and only then are executed according to their "salience" turn.
And on the moment of evaluation $resource1.amount is 5, that is why third rule wasn't fired. If you put a number more than 10 in the first rule the 3d rule will fire. And if you don't set amount at all - it leads to exception.
How can I solve this issue so that the 3d rule fires?

推荐答案

我的猜测是Drools不理解表达式 Double.parseDouble(amount)>更改事实的金额时,必须重新评估10 。问题与您编写表达式的方式有关。

My guess is that Drools doesn't understand that the expression Double.parseDouble(amount) > 10 must be re-evaluated when you change the amount of your fact. The problem is related with the way you are writing your expression.

您可以在另一个问题。看一下另一种解决方案 部分。

You can take a look at my answer in this other question. Take a look at the "Another solution" part.

我建议您做的就是修改模型并添加 getAmountAsDouble()方法,以便您在其中进行转换。您还需要注释 setAmount()方法,以使Drools知道它修改了 getAmountAsDouble():

What I would suggest you to do is to modify your model and add a getAmountAsDouble() method to you class so the conversion happens inside it. You will also need to annotate the setAmount() method to let Drools know that it modifies the value returned by getAmountAsDouble():

public class Resource {

  private String amount;

  @Modifies( { "amountAsDouble" } )
  private void setAmount(String amount){
    this.amount = amount;
  }

  private String getAmount(){
    return this.amount;
  }

  private String getAmountAsDouble(){
    return Double.parseDouble(this.amount);
  }

}

现在,您的规则可以重写为:

Now your rule can be rewritten as:

rule "Rule 3"
salience 10
when
    $resource1: Resource(name == "Resource 1", 
    amountAsDouble > 10)
then
    System.out.println("Rule is fired");
end

希望有帮助,

这篇关于如何在Drools中控制规则评估(或规则执行)阶段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆