问题
Am creating a small rule engine and using drools for it. My design is like the developer (that's me :)) will develop dsl and a business user can create rules (dslr).
dsl file
[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 file
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
The rest of the java code is similar to the one given in examples. In this code am getting the following error
Error
Line 15:4 mismatched input 'then' in rule "Discount For Purchase-1"
Whereas the below dslr works fine
rule "Discount For Purchase-1"
when (When purchase amount is greater than "100")
then
Give "5" Percentage Discount
end
Generated DRL
when (e : Event(EventAction.isPurchaseGreaterThan(e,100))) && (e : Event(EventAction.isCustomerTierEqualTo(e,"Silver"))
Note on this Generated DRL - I might get duplicate variable error for 'e'. That's another problem. But just to sort out this problem i've even tried modifing the second variable to 'e1' in dsl.
And for your information i've tried the below to resolve the error, but noting helped me out
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"));
Update :
Generated 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)
can somebody help me with this? Thanks in advance.
回答1:
You are about to combine two patterns (using class EventAction) at top level, so no operator is necessary, and &&
would be wrong for combining patterns anyway - it is available for constraints within patterns.
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
I wonder whether you have indeed the combination of two Event-s in mind. If not, it's better to combine the constraints within one pattern - although this is a bit tricky. (See the doc.) Alternatively, you can indeed force the identity of another fact bound to a second pattern (of the same class) by using something like this == e
in an additional constraint.
Edit Now that you have added the expanded text, it stands out: Event(EventAction.isCustomerTierEqualTo(e1,"Silver") misses a closing parenthesis at the end, same thing in the other rule. Fix the substitution rule in the DSL.
You can use the same variable(s) in any number of rules, but you cannot bind two patterns within the same rule to the same variable. You may have to redesign your DSL a little, e.g.
# 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}
The DSLR becomes:
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
expands to
when
$person:Person(call_count < 10 || name == "Joe", points > 5)
then
Of course, you'll need the definitions for the operators (or your functions)
[condition][]is greater than=>
[condition][]is equal to===
The initial hyphen is essential, and you need something ("his" or "her") in front of the first parameter ({field}
).
回答2:
I think something is wrong with the quotes "" in your value 100. Try rewriting as
When]When [Pp]urchase amount is greater than {Value} = = e : Event(EventAction.isPurchaseGreaterThan(e,"{Value}"));
And when writing your rule there is no need to insert quotes. Of course this is true if your Value is String. If it is an int exclude the quotes. another advice in order to see your rules transated you should insert
/# debug: display result
in the start and in the end of your dsl file.
来源:https://stackoverflow.com/questions/39898193/drools-grouping-multiple-dsl-conditions-in-dslrs-when-part-throws-error