如何按顺序为相同类型的事实编写规则



我们正在尝试为相同类型的对象编写规则。类型A的对象具有属性valid=true、valid=false、valid=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找到的位置">

请记住,规则引擎的要点是将事实与规则相匹配,然后激发所有相关的事实。在你的情况下,所有的规则都可以触发,因为你把所有4个事实都添加到工作记忆中。第一条规则找到匹配的事实b并激发,第二条规则找到匹配对事实c并激发,最后第三条规则找到相匹配的事实d并激发。这都是有意为之的行为。也就是说,我确实看到了解决这个问题的两种潜在方法:

1) 您可以在第二条规则中添加一个条件,即找不到任何与第一条规则匹配的事实。你的LHS看起来是这样的:

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

这是可行的,但取决于你想用这种方式编写多少规则,这可能很快就会变得麻烦

2) 您可以使用规则流组以更可控的方式启动规则。在您的情况下,每个规则都在自己的组中,在组执行结束时,您可以检查第一个规则修改的布尔事实(您可以在基元类型上创建事实),以确定是完成执行还是转到下一个组。你也可以对议程组做同样的事情,把算法的"智能"放在主程序中,而不是放在规则流中。(仍然需要布尔事实)

希望这能有所帮助。

我想您要找的是运算符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"。我不确定这是否是你真正想要的。

希望有帮助,

最新更新