如何按顺序为同一类型的事实编写规则?
how to write rules for same type of facts sequentially?
我们正在尝试为相同类型的对象编写规则。
存在具有 属性 valid=true ,valid=false,valid=NA 的 typeA 对象。条件是我们要按顺序触发规则
facts valid=="true" && space=="true" 如果它没有为所有提供的事实提供输出,那么它应该转到下一个规则
facts valid=="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**
我们只希望输出 "location found at A" 因为其中一个事实通过了这个条件。但它返回的输出为 "location found at A"、"location found at B"、"location found at C"
请记住,规则引擎的要点是将事实与规则相匹配,然后触发所有相关规则。在您的情况下,所有规则都可以触发,因为您将所有 4 个事实添加到工作记忆中。第一条规则找到匹配事实 b 并触发,第二条规则找到匹配事实 c 并触发,最后第三条规则找到匹配事实 d 并触发。这都是预期的行为。
也就是说,我确实看到了解决该问题的两种可能方法:
1) 您可以在第二条规则中添加一个条件,即找不到与第一条规则匹配的任何事实。你的 LHS 看起来像这样:
when
$typeA: TypeA(valid=="NA" && space=="true")
not (exists (TypeA(valid=="true" && space=="true")))
这可行,但取决于您要以这种方式编写多少规则,这很快就会变得很麻烦。
2) 您可以使用规则流组以更可控的方式触发您的规则。在您的情况下,每个规则都在其自己的组中,并且在组执行结束时,您可以检查由第一个规则修改的布尔事实(您可以在原始类型上创建事实)以确定是否完成执行或去下一组。
您也可以对议程组执行相同的操作,并将算法的 "intelligence" 放在主程序中而不是规则流中。 (为此仍然需要布尔值)
希望对您有所帮助。
我认为你要找的是运算符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"
。我不确定这是否是您真正想要的。
希望对您有所帮助,
我们正在尝试为相同类型的对象编写规则。 存在具有 属性 valid=true ,valid=false,valid=NA 的 typeA 对象。条件是我们要按顺序触发规则
facts valid=="true" && space=="true" 如果它没有为所有提供的事实提供输出,那么它应该转到下一个规则 facts valid=="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**
我们只希望输出 "location found at A" 因为其中一个事实通过了这个条件。但它返回的输出为 "location found at A"、"location found at B"、"location found at C"
请记住,规则引擎的要点是将事实与规则相匹配,然后触发所有相关规则。在您的情况下,所有规则都可以触发,因为您将所有 4 个事实添加到工作记忆中。第一条规则找到匹配事实 b 并触发,第二条规则找到匹配事实 c 并触发,最后第三条规则找到匹配事实 d 并触发。这都是预期的行为。 也就是说,我确实看到了解决该问题的两种可能方法:
1) 您可以在第二条规则中添加一个条件,即找不到与第一条规则匹配的任何事实。你的 LHS 看起来像这样:
when
$typeA: TypeA(valid=="NA" && space=="true")
not (exists (TypeA(valid=="true" && space=="true")))
这可行,但取决于您要以这种方式编写多少规则,这很快就会变得很麻烦。
2) 您可以使用规则流组以更可控的方式触发您的规则。在您的情况下,每个规则都在其自己的组中,并且在组执行结束时,您可以检查由第一个规则修改的布尔事实(您可以在原始类型上创建事实)以确定是否完成执行或去下一组。 您也可以对议程组执行相同的操作,并将算法的 "intelligence" 放在主程序中而不是规则流中。 (为此仍然需要布尔值)
希望对您有所帮助。
我认为你要找的是运算符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"
。我不确定这是否是您真正想要的。
希望对您有所帮助,