Алгоритм проверки состояния таблицы решений Drools

У меня есть вопрос о том, как оцениваются условия для Таблиц Решений Drools. Я думал, что условия оценивались слева направо, и если левый крайний столбец, который он проверял для данного правила, был ложным, он не проверял бы остальные условия.

Одна из причин, по которой это важно для меня, заключается в том, чтобы поставить наиболее узкие условия в крайнее левое положение. Это означало бы, что объекты будут выгружаться раньше, а не большинство объектов, удовлетворяющих широкому условию, и продолжающих проверять дополнительные условия.

Тем не менее, это не то поведение, которое я наблюдал в модульном тесте, о котором я расскажу ниже.

Этот пример прост и не предназначен для демонстрации раннего сужения области действия.

| ------------------ | ------------------- |
| Состояние | Состояние |
|------------------|-------------------|
|myObject          |myObject           |
|------------------|-------------------|
| IsNameEq("$ PARAM")|isValueEq("$ PARAM")|
|------------------|-------------------|
|A                 |1                  |
|A                 |2                  |
|A                 |3                  |
|A                 |4                  |
|A                 |5                  |
|B                 |4                  |
|B                 |5                  |
| Б |6                  |
| Б |7                  |
|------------------|-------------------|

В этом примере isNameEq и isValueEq являются функциями из java-объекта myObject. Пожалуйста, игнорируйте любую небольшую ошибку Drools / отсутствие заявленного импорта, так как я знаю, что мой тест работает нормально, и эта иллюстрация является приблизительной для передачи сценария.

Две функции включают в себя несколько простых журналов, чтобы показать, когда они вызываются. Для объекта с именем =A и значением =3 я бы ожидал, что функция isValueEq никогда не будет вызываться для правил с буквой B в столбце имени (крайнем левом), потому что объект не выполняет это условие.

Однако регистрация указывает, что вызовы функций были сделаны в следующем порядке:

  1. isNameEq (А)
  2. isNameEq (В)
  3. isValueEq (1)
  4. isValueEq (2)
  5. isValueEq (3)
  6. isValueEq (4)
  7. isValueEq (5)
  8. isValueEq (6)
  9. isValueEq (7)

Это звучит правильно? Я просто ошибся в своем предположении? Является ли это частью алгоритма повторного вычисления и оценки кэширования (узлов?), Поскольку он не вызывает isValueEq для (B, 4), (B,5)?

Спасибо всем, кто может пролить свет на это для меня!

1 ответ

Каждая строка вашей электронной таблицы переведена в одно правило, например, строка № 1:

rule "whatever 1"
when
    MyObject( isNameEq("A"), isValueEq("1") )
then

и еще один с "А" и "2", и так далее. Каждый вставленный факт оценивается по этим правилам, один за другим.

Преимущество алгоритма (Rete или что-то еще) может не вступить в силу, когда функции скрывают доступ к данным фактов. Вы можете попробовать простые ограничения (name == "A", value == "1") и зарегистрировать доступ путем изменения метода получения; это не повлияет на способ построения оценочной сети.

Другие вопросы по тегам