Выполнение единого правила для группы в Drools - PullRequest
0 голосов
/ 04 ноября 2018

Я работаю над экспертной системой, основанной на законодательстве, у меня много таких правил:

Правило 1: Если сумма изъятия превышает 3000, арестуйте сумму, закон оправдания 100

Правило 2: Если конфискация относится к типу семьи, конфискуйте сумму, закон об оправдании 200

Проблема в том, что действие «Захватить» можно применить только один раз, но мне нужно сохранить историю соблюденных правил, ниже я привожу пример

rule "law 100"

when 
  $seizure: Seizure(amount>3000)
then
  $seizure.getRules().add("Justification: law 100 of the civil that says bla bla");
  $seizure.applyPunishment();

rule "law 200"

when 
  $seizure: Seizure(type == TYPES.Family)
then
  $seizure.getRules().add("Justification: law 200 of the family code that says bla bla");
  $seizure.applyPunishment();

Как я показал выше, мне нужна часть "then", которая сохраняет правило описания "$ seizure.getRules (). Add (" Обоснование: закон гражданского кодекса ");". и мне также это нужно, если "$ seizure.applyPunishing ();" был уже применен в правиле 1, он не будет повторно применяться в правиле 2.

Спасибо за совет

1 Ответ

0 голосов
/ 05 ноября 2018

У вас есть несколько вариантов здесь.

  1. Измените applyPunishment на идемпотентный.

    Вы не показываете код для applyPunishment, но он может выглядеть как

    private boolean alreadySeized = false;
    
    public void applyPunishment() {
        if (alreadySeized) {
            return;
        }
    
        alreadySeized = true;
    

    Вы могли бы также основать это на некоторой другой переменной, которая уже существует. Например. if (seizedAmount > 0) return;. Но трудно сказать, как это может работать без кода.

  2. Вы можете изменить applyPunishment на что-то вроде markForPunishment, которое может выглядеть как

    private boolean markedForPunishment;
    
    public void markForPunishment() {
        markedForPunishment = true;
    }
    

    Затем добавьте правило, например

    rule "Punish"
    
    when
      $seizure: Seizure(markedForPunishment  == true)
    then
      $seizure.applyPunishment();
    

    С соответствующим геттером.

    Ваши другие правила будут называть markForPunishment, а не applyPunishment.

  3. Вы можете использовать flowflow , чтобы отделить оправдания от наказания.

  4. Вы можете установить переменную в предложении then, которое вы используете в своих правилах.

Возможно, есть другие варианты. Главное решение, которое вы должны сделать, это то, хотите ли вы решение MVEL или решение Java. Некоторые из вариантов потребуют изменения обоих.

...