Drools-группировка нескольких условий dsl в dslr, когда часть бросает ошибку

Создаю небольшой движок правил и использую для него слюни. Мой дизайн похож на разработчика (that’s me :)) будет разрабатывать 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");

DSLR-файл

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-I может получить ошибку повторяющейся переменной для ‘e’. Это еще одна проблема. Но чтобы решить эту проблему, я даже попытался изменить вторую переменную на’ e1 ‘ в dsl.

И для вашей информации я попытался ниже, чтобы решить эту ошибку, но отметив, помогли мне

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)

кто-нибудь может мне помочь? Спасибо заранее.

2 ответа

  1. Вы собираетесь объединить два шаблона (используя класс 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 
    

    Я задаюсь вопросом, действительно ли вы имеете в виду сочетание двух событий. Если нет, лучше объединить ограничения в одном шаблоне — хотя это немного сложно. (См. док.) Кроме того, вы действительно можете принудительно идентифицировать другой факт, связанный со вторым шаблоном (того же класса), используя что-то вроде this == eдополнительного ограничения.

    Редактировать
    Теперь, когда вы добавили развернутый текст, он выделяется: 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}
    

    DSLR становится:

    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}).

  2. Я думаю, что-то не так с котировками «» в вашем значении 100. Попробуйте переписать как

    When]When [Pp]urchase amount is greater than {Value} = = e : Event(EventAction.isPurchaseGreaterThan(e,"{Value}"));
    

    И при написании вашего правила нет необходимости вставлять кавычки. Конечно, это верно, если ваше значение String. Если это int, исключите кавычки. еще один совет для того, чтобы увидеть ваши правила transated вы должны вставить

    /# debug: display result

    в начале и в конце файла dsl.