Предоставляет ли Drools готовый механизм для остановки петель, вызванных обратной цепочкой? Если нет, существуют ли методы для решения таких циклов в самих запросах / правилах Drools? Я нашел некоторые исследования, например, Избегание бесконечных циклов в основанных на правилах системах с обратной цепочкой , указывающее, что это повторяющаяся проблема.
При отсутствии изменений эти циклы вызывают OutOfMemoryError
. Я уже пытался:
- Найти параметры конфигурации в Drools для ограничения поведения, но, по-видимому, их нет;
- Шаг через код, пытаясь найти способы нарушить рекурсивное поведение;
- Измените мои правила для проверки возможных циклов, но это приведет либо к частичному добавлению фактов в рабочую память (WM), либо к вычислительно дорогостоящим логам c.
Это самый простой возможный пример, который я мог бы привести, чтобы проиллюстрировать проблему. Предполагая, что отношение HasA
представляет «владение». Когда приведенные ниже факты вставляются в WM и все правила запускаются, факты, выведенные с помощью B C («У Дома есть Джон» и «У Джона есть спальня»), вызывают бесконечное l oop.
- Спальня имеет Джона
- В доме есть Спальня
- У Джона есть Дом
Тип факта (Java класс)
@Role(FACT)
public class HasA {
@Position(0)
private String possessor;
@Position(1)
private String possessee;
... Setters, getters...
}
Запрос Drools
query hasPossession(String possessor, String possessee)
HasA(possessor, possessee)
or
(HasA(z, possessee) and hasPossession(possessor, z;))
end
Код теста
...
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession();
kieSession.insert(new HasA("Bedroom", "John"));
kieSession.insert(new HasA("House", "Bedroom"));
kieSession.insert(new HasA("John", "House"));
kieSession.fireAllRules();
...
Я использовал Drools / K IE API 7.34.0 Финал в этом тесте.