Drools不像专家文档中宣传的那样工作

时间:2012-10-17 01:40:10

标签: drools

我有两个非常简单的规则

rule "Volume Validation"
    salience 10
when 

    avs : AvailabilityStatusAndDiscountDisplay( quantity > 1000 || quantity < 0) 

then    

    avs.setAvailable(false);        
    avs.setDiscountRateUnavailableMessage("Unavailable Quanitity");
end 

rule "Discount Rate Calculation -1"

salience 9

when 

     AvailabilityStatusAndDiscountDisplay( productType == "111",calculated==false, available == true, quantity >= 50) 

     avs:   AvailabilityStatusAndDiscountDisplay()
then    

    avs.setDiscountRate("0.65");
    avs.setCalculated(true);

end

但是当数量为5000且第一条规则将可用设置为false时。第二个“规则”无法看到这种变化并继续进行评估。 尽管如此,https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_SOA_Platform/5/html/JBoss_Rules_5_Reference_Guide/chap-examples.html#id18463514会告知工作内存中更改的对象将被序列中的下一个规则看到。

编辑。非常感谢来自@alicox的帮助

rule "Volume Validation"
salience 10
no-loop true
when 

avs : AvailabilityStatusAndDiscountDisplay( quantity > 1000 || quantity < 0) 

then    

avs.setAvailable(false);        
avs.setDiscountRateUnavailableMessage("Unavailable Quanitity");
update(avs);
end 

rule "Discount Rate Calculation -1"

salience 9

when 

AvailabilityStatusAndDiscountDisplay( productType == "111",calculated==false,   available == true, quantity >= 50) 

avs:   AvailabilityStatusAndDiscountDisplay()
then    

avs.setDiscountRate("0.65");
avs.setCalculated(true);

end

这很有效。

如果我理解正确的话,alicox也建议通过插入方法制作面包屑

then 
     insert (blah = true) //so as not to fire new rule 
    end 
//new rule 
when 
     blah == false

不确定是什么类型的对象。

1 个答案:

答案 0 :(得分:1)

您需要在更改其属性后调用avs上的更新或修改,以便在LHS部分中重新评估它。

同样在你的第二条规则中,LHS可以缩短为以下内容:

avs: AvailabilityStatusAndDiscountDisplay( productType == "111",
           calculated==false, available == true, quantity >= 50) 

调用更新或修改事实将导致再次触发在其LHS部分中引用该规则的规则。如果这不是预期的行为,您有几个选择

1)使用无循环,这将阻止在规则中完成更新,触发自身

2)使用更细粒度的事实。

3)在更新后将面包屑事实插入会话,并在LHS中检查它们是否存在。首先在名为Breadcrumb的模型中定义一个事实类型,并使用字符串属性&#34; name&#34;,然后使用以下内容。

when
  not Breadcrumb(name == "calculationXXXDone")
  ....
then
  ...
  //do some work
  ...
  bc = new Breadcrumb()
  bc.name = "calculationXXXDone"
  insert(bc)