Алгоритм проверки состояния таблицы решений 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 в столбце имени (крайнем левом), потому что объект не выполняет это условие.
Однако регистрация указывает, что вызовы функций были сделаны в следующем порядке:
- isNameEq (А)
- isNameEq (В)
- isValueEq (1)
- isValueEq (2)
- isValueEq (3)
- isValueEq (4)
- isValueEq (5)
- isValueEq (6)
- 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") и зарегистрировать доступ путем изменения метода получения; это не повлияет на способ построения оценочной сети.