如何使用Drools反向链接列出满足目标所需的初始事实?

时间:2015-01-18 14:41:48

标签: drools

我试图使用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 我认为它应该可行,但我还没有找到一种方法来指定一个能够给我预期结果的查询。

提前谢谢。

1 个答案:

答案 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之间的连接仍然缺失。

要确切知道哪些对象导致了另一个对象的断言,您可能需要采用不同的方法。选项包括:

  • 使连接显式:新的A($ s)// $ s绑定到“go2”
  • 使用“insertLogical”在“go2”和A之间建立依赖关系,然后查询TruthMaintenanceSystem

基于TMS的将是我的暂时选择,但它也取决于您的确切要求。

这个用例很常见,可能还有其他选项,包括一些实验,因为它们是在6.3中开发的,但我宁愿先问几个问题。 那就是:你什么时候需要完全发现事实 - 在执行规则期间,还是“离线”?它纯粹是出于审计目的,还是会影响您的业务逻辑?你有多个断言“相同”对象的规则吗?

希望这会有所帮助 的Davide