как написать правила для однотипных фактов последовательно?

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

Facts valid=="true" && space=="true", если он не выдает вывод для всех предоставленных фактов, тогда он должен перейти к следующему правилу. при условии, что факты не дают вывода, тогда только мы хотим перейти к 3-м фактам правила valid=="false" && 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», поскольку один из фактов соответствует этому условию. но он возвращает вывод как «местоположение найдено в A», «местоположение найдено в B», «местоположение найдено в C»


person Monika Gupta    schedule 04.01.2019    source источник


Ответы (2)


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

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

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

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

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

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

person DevAir1    schedule 04.01.2019
comment
Мы смогли добиться того же с помощью групп Agenda .. Спасибо !! - person Monika Gupta; 09.01.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". Я не уверен, что это то, что вы на самом деле ищете или нет.

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

person Esteban Aliverti    schedule 04.01.2019