Как контролировать этапы оценки (или выполнения) правил в Drools? - PullRequest
0 голосов
/ 07 апреля 2019

Я знаю, что "значимость" в Drools обеспечивает контроль в последовательности выполнения правил. Но выше приведен пример проблемы, когда «отличия» больше не могут помочь, с которыми я столкнулся.

Здесь у меня три правила, выполняемые одно за другим:

rule "Rule 1"
salience 30
when

then
    Resource resource1 = new Resource();
    resource1.setName("Resource 1");
    resource1.setAmount("5");
    insert(resource1);
    System.out.println("First");
end

rule "Rule 2"
salience 20
//no-loop (interesting, it doesn't lead to a loop)
when
    $resource1: Resource(name == "Resource 1")
then
    modify($resource1) {setAmount("20")};
    System.out.println("Second");
end

rule "Rule 3"
salience 10
when
    $resource1: Resource(name == "Resource 1", 
    Double.parseDouble(amount) > 10)
then
    System.out.println("Rule is fired");
end

Я ожидал, что третье правило сработало, и в консоли есть строка «Правило сработало», но оно не выполнено.
Как я понимаю, проблема связана со стадией оценки правил, когда все три правила оцениваются сразу перед выполнением, и только после этого выполняются в соответствии с их поворотом «значимости».
А на момент оценки $ resource1.amount равно 5 , поэтому третье правило не было выполнено. Если вы поместите число больше 10 в первое правило, правило 3d сработает. А если вы вообще не установите сумму - это приведет к исключению.
Как я могу решить эту проблему, чтобы сработало правило 3d?

Ответы [ 3 ]

2 голосов
/ 08 апреля 2019

Я предполагаю, что Drools не понимает, что выражение Double.parseDouble(amount) > 10 должно быть пересмотрено, когда вы измените amount вашего факта.Проблема связана с тем, как вы пишете свое выражение.

Вы можете посмотреть на мой ответ в этот другой вопрос .Взгляните на «Другое решение» деталь.

Я бы предложил вам изменить модель и добавить метод getAmountAsDouble() в ваш класс, чтобы преобразование происходило внутри.Это.Вам также понадобится аннотировать метод setAmount(), чтобы Drools знал, что он изменяет значение, возвращаемое getAmountAsDouble():

public class Resource {

  private String amount;

  @Modifies( { "amountAsDouble" } )
  private void setAmount(String amount){
    this.amount = amount;
  }

  private String getAmount(){
    return this.amount;
  }

  private String getAmountAsDouble(){
    return Double.parseDouble(this.amount);
  }

}

Теперь ваше правило можно переписать так:

rule "Rule 3"
salience 10
when
    $resource1: Resource(name == "Resource 1", 
    amountAsDouble > 10)
then
    System.out.println("Rule is fired");
end

Надеюсь, это поможет,

0 голосов
/ 03 июля 2019

Так что это была ошибка, и теперь она исправлена ​​в одном из последних обновлений. Вот вопрос: https://issues.jboss.org/browse/DROOLS-3972

0 голосов
/ 07 апреля 2019

Посмотрите в документах для Повестки дня / групп активации, вы можете контролировать выполнение групп правил, используя эту концепцию

...