我试图使用Drools反向链接来找出将对象插入工作内存所需的事实。 在下面的例子中,我希望得到事实" go2"。
rule "ins a"
when
String( this == "go2" )
then
insert(new A());
end
rule "Run"
when
then
insert(new String("go1"));
end
rule "Test isThereAnyA"
when
String( this == "go1" )
isThereAnyA(a;)
then
System.out.println( "you can get " + a );
end
query isThereAnyA (A a)
a := A()
end
我一直在查看官方文档中的示例 http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21289 但是他们表现出不同的情况(这些例子中的规则并没有创造新的事实)
从图表中 http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21240 我认为它应该可行,但我还没有找到一种方法来指定一个能够给我预期结果的查询。
提前谢谢。
答案 0 :(得分:3)
简短回答:
不幸的是,反向链接不能用于此目的。 在这种情况下,它不会给你“go2”。
答案很长:
在Drools中,后向链接(BC)是一种以目标驱动的方式查询WM的方法,而不是追溯正常前向链接推理过程的派生图的方法。
BC允许规则“Test”通过查询“isThereAnyA”检索As,并可能调用其他查询,但不允许在“A”和“go2”之间找到“生产”链接。原因是“when..then..insert ..”不会在触发事实和断言结论之间建立任何联系,而后向链接不会改变它。
你可以用BC做什么:
query isThereAnyA_InPresenceOfA_String( A a )
isThereAnyString( $s ; )
a := A()
end
query isThereAnyString( String $s )
$s := String( this == "go2" )
end
只有当字符串“go2”存在(仍然存在)时,才会拾取。但是,您会注意到A的特定实例与导致其断言的特定String之间的连接仍然缺失。
要确切知道哪些对象导致了另一个对象的断言,您可能需要采用不同的方法。选项包括:
基于TMS的将是我的暂时选择,但它也取决于您的确切要求。
这个用例很常见,可能还有其他选项,包括一些实验,因为它们是在6.3中开发的,但我宁愿先问几个问题。 那就是:你什么时候需要完全发现事实 - 在执行规则期间,还是“离线”?它纯粹是出于审计目的,还是会影响您的业务逻辑?你有多个断言“相同”对象的规则吗?
希望这会有所帮助 的Davide