首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Drools -当部件抛出错误时,dslr中的多个dsl条件分组

Drools -当部件抛出错误时,dslr中的多个dsl条件分组
EN

Stack Overflow用户
提问于 2016-10-06 14:06:03
回答 2查看 1.6K关注 0票数 0

我正在创建一个小规则引擎,并为它使用drools。我的设计就像开发人员(即我:)将开发dsl,业务用户可以创建规则(dslr)。

dsl文件

代码语言:javascript
复制
[When]When [Pp]urchase amount is greater than "{Value}" = e : Event(EventAction.isPurchaseGreaterThan(e,{Value}))
[When]If [Cc]ustomer tier equals to "{CustomerTier}"=e1 : Event(EventAction.isCustomerTierEqualTo(e1,"{CustomerTier}")
[Then]Give "{Discount}" Percentage Discount = RewardAction.applyDiscount(e, {Discount});
[Then]Suggest Redemption = System.out.println("Redemption Suggested");

dslr文件

代码语言:javascript
复制
rule "Discount For Purchase-1"
    when (When purchase amount is greater than "100") && (If customer tier equals to "Silver")
    then     #Error is thrown in this line
        Give "5" Percentage Discount 
end 

其余的java代码类似于示例中给出的代码。在这段代码中,将得到以下错误

误差

代码语言:javascript
复制
Line 15:4 mismatched input 'then' in rule "Discount For Purchase-1"

而下面的dslr工作得很好

代码语言:javascript
复制
rule "Discount For Purchase-1"
    when (When purchase amount is greater than "100")
    then
        Give "5" Percentage Discount 
end 

生成的DRL

代码语言:javascript
复制
when (e : Event(EventAction.isPurchaseGreaterThan(e,100))) && (e : Event(EventAction.isCustomerTierEqualTo(e,"Silver"))

注意到这个生成的DRL -我可能会得到'e‘的重复变量错误。这是另一个问题。但是为了解决这个问题,我甚至尝试修改dsl中的第二个变量“e1”。

关于您的信息,我尝试了下面的方法来解决这个错误,但是注意到它帮助了我

代码语言:javascript
复制
When (When purchase amount is greater than "100" && If customer tier equals to "Silver")
When (When purchase amount is greater than "100" and If customer tier equals to "Silver")
When ((When purchase amount is greater than "100") && (If customer tier equals to "Silver"))
When ((When purchase amount is greater than "100") and (If customer tier equals to "Silver"))
When ((When purchase amount is greater than "100") and (If customer tier equals to "Silver"));
When ((When purchase amount is greater than "100") && (If customer tier equals to "Silver"));

更新:

生成的drl

代码语言:javascript
复制
=== DRL xpanded from DSLR ===
   1  #created on: 5 Oct, 2016
   2  package com.test.loyalty.rules
   3  
   4  #list any import classes here.
   5  import com.test.loyalty.*
   6  import com.test.loyalty.model.*
   7  import com.test.loyalty.util.*
   8  
   9  
  10  
  11  #declare any global variables here
  12  
  13  rule "Discount For Purchase-1"
  14      when 
  15        e : Event(EventAction.isPurchaseGreaterThan(e,100))
  16        e1 : Event(EventAction.isCustomerTierEqualTo(e1,"Silver")
  17      then
  18          System.out.println("Redemption Suggested"); 
  19  end
  20  
  21  rule "Discount For Purchase-2"
  22      when
  23          e : Event(EventAction.isPurchaseGreaterThan(e,100))
  24        e1 : Event(EventAction.isCustomerTierEqualTo(e1,"Gold")
  25      then
  26          System.out.println("Redemption Suggested"); 
  27  end
  28  


=============================
[ERR 102] Line 17:4 mismatched input 'then' in rule "Discount For Purchase-1"
17
[ERR 102] Line 25:4 mismatched input 'then' in rule "Discount For Purchase-2"
25
java.lang.IllegalArgumentException: Could not parse knowledge.
    at com.test.loyalty.LoyaltyTest.readKnowledgeBase(LoyaltyTest.java:124)
    at com.test.loyalty.LoyaltyTest.init(LoyaltyTest.java:104)
    at com.test.loyalty.LoyaltyTest.main(LoyaltyTest.java:38)

有人能帮我吗?提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-06 14:34:48

您即将在顶层组合两种模式(使用类EventAction),因此不需要操作符,而且&&也不适合组合模式--它适用于模式中的约束。

代码语言:javascript
复制
rule "Discount For Purchase-1"
when
    When purchase amount is greater than "100"
    If customer tier equals to "Silver"
then    
    Give "5" Percentage Discount 
end 

我想知道你是否真的把这两件事结合在一起。如果不是,最好将约束合并到一个模式中--尽管这有点棘手。(见医生)或者,通过在附加约束中使用类似于this == e的内容,您确实可以强制将另一个事实的标识绑定到另一个模式(同一类)。

编辑现在已经添加了扩展的文本,它非常突出:事件(EventAction.isCustomerTierEqualTo(e1,"Silver") )在末尾遗漏了一个结束括号,这在另一条规则中是一样的。修正DSL中的替换规则。

可以在任意数量的规则中使用相同的变量,但不能将同一规则中的两种模式绑定到同一变量。你可能需要重新设计一下你的DSL。

代码语言:javascript
复制
# creates the Person pattern and binds $person
[condition][]There is a Person with=$person:Person()

# write a comparison using a field reference and a value
[condition][]- his {field} {operator} {value}=
             {field} {operator} {value}

萨尔瓦多共和国成为:

代码语言:javascript
复制
when
    There is a Person with
    - his call_count is less than 10 or name is equal to "Joe" 
    - his points is greater than 5
then

扩展到

代码语言:javascript
复制
when
    $person:Person(call_count  <  10 || name == "Joe", points  >  5)
then

当然,您需要操作符(或函数)的定义。

代码语言:javascript
复制
[condition][]is greater than=>
[condition][]is equal to===

初始连字符是必不可少的,您需要在第一个参数({field})前面有一些东西(“他的”或“她的”)。

票数 0
EN

Stack Overflow用户

发布于 2016-10-07 07:38:59

我认为你的价值100中的引号"“有问题。试着重写为

代码语言:javascript
复制
When]When [Pp]urchase amount is greater than {Value} = = e : Event(EventAction.isPurchaseGreaterThan(e,"{Value}"));

在编写规则时,不需要插入引号。当然,如果您的值是String,则这是正确的。如果是int,则排除引号。另一个建议,为了看到您的规则被转换,您应该插入

/# debug: display result

在dsl文件的开头和结尾。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39898193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档