如何使用 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我认为它应该有效,但我还没有找到一种方法来指定给我预期结果的查询。

提前谢谢你。

简短回答:

不幸的是,向后链接不能用于此目的。在这种情况下,它不会给你"go2"。

长答案:

在 Drools 中,反向链接 (BC) 是一种以目标驱动的方式查询 WM 的方法,而不是追溯正常正向链推理过程的派生图的方法。

BC允许规则"Test"通过查询"isThereAnyA"检索As,并可能调用其他查询,但不允许在"A"和"go2"之间找到"生产"链接。原因是"当.然后。。插入.." 不会在触发事实和断言结论之间建立任何链接,反向链接不会改变它。

你可以用BC做的是这样的:

query isThereAnyA_InPresenceOfA_String( A a )
   isThereAnyString( $s ; )       
   a := A()
end 
query isThereAnyString( String $s )
   $s := String( this == "go2" )
end

仅当字符串"go2"(仍然)存在时,才会选取 As。但是,您会注意到,A 的特定实例与导致其断言的特定字符串之间的连接仍然缺失。

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

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

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

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

希望这有帮助大卫

最新更新