如何依次为相同类型的事实编写规则?

时间:2019-01-04 12:31:42

标签: java drools

我们正在尝试为相同类型的对象编写规则。 有类型A的对象,其属性为有效=真,有效=假,有效= NA。条件是我们要按顺序触发规则,使

事实有效==“ true” && space ==“ true”如果未提供所有提供的事实的输出,则应转到下一条规则 事实有效==“ NA” && space ==“ true”如果提供的任何事实均未提供输出,则仅我们要执行第三条规则 事实有效==“ 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处找到位置”

2 个答案:

答案 0 :(得分:0)

请记住,规则引擎的主要目的是将事实与规则进行匹配,然后触发所有相关规则。对于您而言,所有规则都可以触发,因为您将所有4个事实都添加到了工作内存中。第一条规则找到匹配的事实b并触发,第二条规则找到匹配的事实c并触发,最后第三条规则找到匹配的事实d并触发。这都是预期的行为。 也就是说,我确实看到了解决该问题的两种潜在方法:

1)您可以在第二条规则中添加关于找不到与第一条规则匹配的任何事实的条件。您的LHS如下所示:

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

这可以工作,但是根据您要编写多少条规则,这很快就会变得很麻烦。

2)您可以使用ruleflow-groups以更可控的方式触发规则。在您的情况下,每个规则都将在其自己的组中,并且在组执行结束时,您可以检查由第一条规则修改的布尔事实(可以在原始类型上创建事实),以确定是否完成执行或转到下一组。 您也可以对议程组执行相同的操作,并将算法的“智能”置于主程序中,而不是放在规则流中。 (为此仍需要布尔事实)

希望这会有所帮助。

答案 1 :(得分:0)

我认为您正在寻找的是运营商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"。我不确定这是否是您真正想要的东西。

希望有帮助,