我们正在尝试为相同类型的对象编写规则。类型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"
。我不确定这是否是你真正想要的。
希望有帮助,