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

如何使用Drools反向链接列出满足目标所需的初始事实?,drools,Drools,我尝试使用Drools反向链接来找出将对象插入工作内存需要哪些事实。 在下面的示例中,我希望得到事实“go2” 我一直在看官方文档中的例子 但它们显示了不同的情况(这些示例中的规则不会产生新的事实) 从图表上看 我认为它应该可以工作,但我还没有找到一种方法来指定一个能够提供预期结果的查询 提前谢谢。简短回答: 不幸的是,反向链接不能用于此目的。 在这种情况下,它不会给你“go2” 长答覆: 在Drools中,反向链接(BC)是一种以目标驱动的方式查询WM的方法,而不是一种追溯正常正向链接推理过程

我尝试使用Drools反向链接来找出将对象插入工作内存需要哪些事实。 在下面的示例中,我希望得到事实“go2”

我一直在看官方文档中的例子 但它们显示了不同的情况(这些示例中的规则不会产生新的事实)

从图表上看 我认为它应该可以工作,但我还没有找到一种方法来指定一个能够提供预期结果的查询

提前谢谢。

简短回答:

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

长答覆:

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

BC允许规则“Test”通过查询“isThereAnyA”检索As,并可能调用其他查询,但不允许查找“A”和“go2”之间的“production”链接。原因是“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的特定实例和导致其断言的特定字符串之间的连接仍然缺失

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

  • 明确连接:绑定到“go2”的新A($s)/$s
  • 使用“insertLogical”在“go2”和a之间建立依赖关系,然后查询TruthMaintenance系统
基于TMS的将是我的初步选择,但它也取决于您的确切要求

这个用例很常见,可能还有其他选项,包括一些在6.3中开发的实验性选项,但我宁愿先问几个问题。 也就是说:在执行规则的过程中,或者“离线”时,您需要准确地发现事实吗?它是纯粹用于审计目的,还是会影响您的业务逻辑?可以有多个规则断言“同一”对象吗

希望这有帮助
Davide

用例是:用户输入业务的某些期望状态(目标)(即,为某些POJO分配一组值)。规则是这样的:如果业务有X,那么它就有Y我想知道需要哪些事实才能获得Y,因此我可以建议用户:你应该尝试获得X(我知道应该避免像“谢谢”这样的评论,但我无能为力:非常感谢你的及时回答),所以为了回答你的问题,我认为我需要“离线”发现事实(规则甚至可能无法执行)。没有用于审核的结果,结果会影响系统的输出。最后一个问题很棘手:您想让我拥有多个断言“相同”对象的规则吗我的意思是,我不知道你要去哪里,目前有几个规则断言同一个对象,但我对此有一些控制,因为POJO中有一个“name”属性可以更改(此外,我使用equalsBehavior=“equality”,所以我可以更改equals方法)。如果你真的觉得冒险,您可以尝试这样的方法:在这种特殊(而且是实验性的!!)的后台链接中,如果满足条件,则允许查询插入对象。因此,您从描述您的状态的事实(Y)开始,查询应用条件并确定可能的前提条件(X)。当X被断言并连接到Y的实例时,您最终可以检查工作内存并查看建议。请注意,这是一个不受支持的实验性功能,在不久的将来可能会发生变化。我一直在研究BC的诱因风格(我甚至对其做出了一点贡献),我认为只要我能自动为每个规则生成一个诱因查询,并将其前后条件联系起来,它就可能起作用。你认为可以做到吗?你能给我一些建议吗?我发布了我在这方面的进展。你能提供一个你现在想写的成对规则/查询的例子吗?谢谢
query isThereAnyA_InPresenceOfA_String( A a )
   isThereAnyString( $s ; )       
   a := A()
end 
query isThereAnyString( String $s )
   $s := String( this == "go2" )
end