Как написать правила для фактов того же типа последовательно? - PullRequest
0 голосов
/ 04 января 2019

Мы пытаемся написать правила для однотипных объектов. Существуют объекты типа A, имеющие свойство valid = true, valid = false, valid = NA. Условие - мы хотим запускать правила в такой последовательности, чтобы

факты действительны == "истина" && пробел == "истина", если он не дает вывод для всех предоставленных фактов, тогда он должен перейти к следующему правилу факты действительны == "NA" && space == "true", если какой-либо из предоставленных фактов не дает вывод, тогда только мы хотим перейти к третьему правилу факты действительны == "ложь" && space == "true".

Если первое правило само выдает результат, то мы не хотим переходить к следующему правилу.

наш фрагмент кода выглядит так:

**TypeA a =new TypeA();
a.setValid("true");
a.setSpace("false");

TypeA b = new TypeA();
b.setValid("true");
b.setSpace("true");

TypeA c=new TypeC();
b.setValid("NA");
b.setSpace("true");

TypeA d=new TypeC();
d.setValid("false");
d.setSpace("true");
List<TypeA> typeAList=new ArrayList<>();
typeAList.add(a);
typeAList.add(b);
typeAList.add(c);
typeAList.add(d);**

// код для создания KieBase

**kieBase.newStatelessKieSession().execute(typeAList);**

**rule "5"
salience 5
when
    $typeA: TypeA(valid=="true" && space=="true")
then
System.out.println("location found at A");
end

rule "4"
salience 4
when
    $typeA: TypeA(valid=="NA" && space=="true")
then
System.out.println("location found at B");
end

rule "3"
salience 3
when
    $typeA: TypeA(valid=="false" && space=="true")
then
System.out.println("location found at C");
end**

Мы хотим выводить только как «местоположение, найденное в А», поскольку один из фактов проходит это условие но он возвращает выходные данные как «местоположение, найденное в A», «местоположение, найденное в B», «местоположение, найденное в C»

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Я думаю, что вы ищете оператора exists:

rule "5"
salience 5
when
  exists TypeA(valid=="true" && space=="true")
then
  System.out.println("location found at A");
end

rule "4"
salience 4
when
  exists TypeA(valid=="NA" && space=="true")
then
  System.out.println("location found at B");
end

rule "3"
salience 3
when
  exists TypeA(valid=="false" && space=="true")
then
  System.out.println("location found at C");
end

`` ``

Обратите внимание, что при использовании оператора exists вы не можете привязать к нему переменную. Так что это решение не работает, если вам нужен экземпляр TypeA в правой части ваших правил.

Другое ограничение этого решения состоит в том, что даже если отдельное правило будет активировано один раз, независимо от того, сколько у вас совпадающих фактов, отдельные правила все равно могут быть активированы. Таким образом, если вы вставите 10 FactA("true","true"), вы получите только один "location found at A" напечатанный, как только вы вставите FactA("NA", "true"), вы получите ""location found at B" напечатанный. Я не уверен, что это то, что вы на самом деле ищете или нет.

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

0 голосов
/ 04 января 2019

Имейте в виду, что главная задача механизма правил - сопоставлять факты с правилами, а затем запускать все соответствующие. В вашем случае все правила могут сработать, так как вы добавляете все 4 факта в рабочую память. Первое правило находит совпадающий факт b и срабатывает, второе правило находит совпадающий факт c и срабатывает, и, наконец, третье правило находит совпадающий факт d и срабатывает. Это все намеренное поведение. Тем не менее, я вижу два возможных способа решения этой проблемы:

1) Вы можете добавить условие во втором правиле о том, что не найдете ни одного факта, соответствующего первому правилу. Ваша LHS будет выглядеть так:

when
    $typeA: TypeA(valid=="NA" && space=="true")
    not (exists (TypeA(valid=="true" && space=="true")))

Это будет работать, но в зависимости от того, сколько правил вы хотите написать таким образом, это может быстро стать громоздким.

2) Вы можете использовать правила-группы для более строгого управления вашими правилами. В вашем случае каждое правило будет находиться в отдельной группе, и в конце выполнения группы вы можете проверить логический факт (вы можете создавать факты для примитивных типов), который изменяется первым правилом, чтобы определить, завершить ли выполнение. или перейти к следующей группе. Вы также можете сделать то же самое с повесткой дня вместо групп и поместить «интеллект» алгоритма в основную программу, а не в поток правил. (для этого все еще нужны логические факты)

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

...