Drools - 在部分抛出错误时在 dslr 中分组多个 dsl 条件
Drools - Grouping multiple dsl conditions in dslr's when part throws error
我正在创建一个小型规则引擎并为其使用 drools。我的设计就像开发人员(就是我 :))将开发 dsl 而业务用户可以创建规则 (dslr)。
dsl文件
[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");
单反文件
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 代码的其余部分与示例中给出的代码类似。在此代码中出现以下错误
错误
Line 15:4 mismatched input 'then' in rule "Discount For Purchase-1"
而下面的 dslr 工作正常
rule "Discount For Purchase-1"
when (When purchase amount is greater than "100")
then
Give "5" Percentage Discount
end
生成的 DRL
when (e : Event(EventAction.isPurchaseGreaterThan(e,100))) && (e : Event(EventAction.isCustomerTierEqualTo(e,"Silver"))
关于此生成的 DRL 的注释 - 我可能会收到 'e' 的重复变量错误。那是另一个问题。但为了解决这个问题,我什至尝试在 dsl 中将第二个变量修改为 'e1'。
为了您的信息,我已经尝试了以下方法来解决错误,但注意到帮助了我
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
=== 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)
有人可以帮我解决这个问题吗?提前致谢。
您将在顶层组合两个模式(使用 class EventAction),因此不需要运算符,并且 &&
无论如何组合模式都是错误的 - 它可用于约束在模式中。
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
不知你是否真的想到了两个Event-s的组合。如果不是,最好将约束组合在一个模式中——尽管这有点棘手。 (请参阅文档。)或者,您确实可以通过在附加约束中使用类似 this == e
的内容来强制另一个事实的身份绑定到第二个模式(相同 class)。
编辑
现在您已经添加了扩展文本,它很突出: Event(EventAction.isCustomerTierEqualTo(e1,"Silver") 在末尾错过了一个右括号,在另一个规则中也是如此。修复替换规则DSL.
您可以在任意数量的规则中使用相同的变量,但不能将同一规则中的两个模式绑定到同一变量。您可能需要稍微重新设计您的 DSL,例如
# 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}
单反变成:
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
扩展到
when
$person:Person(call_count < 10 || name == "Joe", points > 5)
then
当然,您需要运算符(或您的函数)的定义
[condition][]is greater than=>
[condition][]is equal to===
开头的连字符是必不可少的,您需要在第一个参数 ({field}
) 前面加一些东西 ("his" 或 "her")。
我认为您的值 100 中的引号 "" 有问题。请尝试重写为
When]When [Pp]urchase amount is greater than {Value} = = e : Event(EventAction.isPurchaseGreaterThan(e,"{Value}"));
并且在编写规则时无需插入引号。当然,如果您的值是字符串,这是正确的。如果它是一个 int 排除引号。另一个建议,为了看到你的规则被翻译,你应该插入
/# debug: display result
在您的 dsl 文件的开头和结尾。
我正在创建一个小型规则引擎并为其使用 drools。我的设计就像开发人员(就是我 :))将开发 dsl 而业务用户可以创建规则 (dslr)。
dsl文件
[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");
单反文件
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 代码的其余部分与示例中给出的代码类似。在此代码中出现以下错误
错误
Line 15:4 mismatched input 'then' in rule "Discount For Purchase-1"
而下面的 dslr 工作正常
rule "Discount For Purchase-1"
when (When purchase amount is greater than "100")
then
Give "5" Percentage Discount
end
生成的 DRL
when (e : Event(EventAction.isPurchaseGreaterThan(e,100))) && (e : Event(EventAction.isCustomerTierEqualTo(e,"Silver"))
关于此生成的 DRL 的注释 - 我可能会收到 'e' 的重复变量错误。那是另一个问题。但为了解决这个问题,我什至尝试在 dsl 中将第二个变量修改为 'e1'。
为了您的信息,我已经尝试了以下方法来解决错误,但注意到帮助了我
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
=== 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)
有人可以帮我解决这个问题吗?提前致谢。
您将在顶层组合两个模式(使用 class EventAction),因此不需要运算符,并且 &&
无论如何组合模式都是错误的 - 它可用于约束在模式中。
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
不知你是否真的想到了两个Event-s的组合。如果不是,最好将约束组合在一个模式中——尽管这有点棘手。 (请参阅文档。)或者,您确实可以通过在附加约束中使用类似 this == e
的内容来强制另一个事实的身份绑定到第二个模式(相同 class)。
编辑 现在您已经添加了扩展文本,它很突出: Event(EventAction.isCustomerTierEqualTo(e1,"Silver") 在末尾错过了一个右括号,在另一个规则中也是如此。修复替换规则DSL.
您可以在任意数量的规则中使用相同的变量,但不能将同一规则中的两个模式绑定到同一变量。您可能需要稍微重新设计您的 DSL,例如
# 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}
单反变成:
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
扩展到
when
$person:Person(call_count < 10 || name == "Joe", points > 5)
then
当然,您需要运算符(或您的函数)的定义
[condition][]is greater than=>
[condition][]is equal to===
开头的连字符是必不可少的,您需要在第一个参数 ({field}
) 前面加一些东西 ("his" 或 "her")。
我认为您的值 100 中的引号 "" 有问题。请尝试重写为
When]When [Pp]urchase amount is greater than {Value} = = e : Event(EventAction.isPurchaseGreaterThan(e,"{Value}"));
并且在编写规则时无需插入引号。当然,如果您的值是字符串,这是正确的。如果它是一个 int 排除引号。另一个建议,为了看到你的规则被翻译,你应该插入
/# debug: display result
在您的 dsl 文件的开头和结尾。