推理引擎根据内部规则计算匹配集

时间:2010-05-24 13:56:28

标签: java logic rules rule-engine inference-engine

我有一组带有属性和一系列规则的对象,当应用于对象集时,它们提供了这些对象的子集。为了使这更容易理解,我将提供一个具体的例子。

我的对象是人,每个人都有三个属性:原籍国,性别和年龄组(所有属性都是离散的)。我有一堆规则,比如“来自美国的所有男性”,它们与这一大型对象的子集相对应。

我正在寻找一个现有的Java“推理引擎”或类似的东西,它将能够从规则映射到一部分人,或者建议如何创建我自己的。我已阅读过规则引擎,但该术语似乎专门用于外部化业务规则的专家系统,通常不包括任何高级形式的推理。以下是我必须处理的更复杂场景的一些示例:

  1. 我需要规则的结合。因此,当提出“包括所有男性”和“排除10-20岁年龄组中的所有美国人”时,我只对美国以外的男性以及美国境内10岁以外的男性感兴趣 - 20岁年龄组。

  2. 规则可能有不同的优先级(明确定义)。因此,“排除所有男性”的规则将覆盖“包括所有美国男性”的规则。

  3. 规则可能存在冲突。所以我可以同时包括“包括所有男性”和“排除所有男性”,在这种情况下,优先事项必须解决问题。

  4. 规则是对称的。所以“包括所有男性”相当于“排除所有女性”。

  5. 规则(或更确切地说,子集)可能具有与之关联的元规则(明确定义)。必须在应用原始规则的任何情况下应用这些元规则,或者如果通过推理到达子集,则必须应用这些元规则。因此,如果将“排除美国”的元规则附加到“包括所有男性”的规则,并且我向引擎提供“排除所有女性”的规则,则应该能够推断“排除所有女性”子集相当于“包括所有男性”子集,因此另外适用“排除美国”规则。

  6. 我很可能没有第5项,但我确实需要提到所有其他属性。我的规则和对象都存储在数据库中,并且可以在任何阶段更新,因此我需要在需要时实例化“推理引擎”并在之后将其销毁。

6 个答案:

答案 0 :(得分:3)

Java中有许多类似Prolog的嵌入式SLD求解器;我最喜欢的方法是使用mini-Kanren for Scala,因为它很干净,允许你使用Scala懒惰地处理查询结果,但我没有在任何深度使用它。有关其他选项,请参阅Embedded Prolog Interpreter/Compiler for Java,以及Ross的回答。

SLD解算器可以处理您的所有条件,前提是它们具有Prolog的一些额外功能:

  1. 规则的结合:基本SLD目标处理;
  2. 规则可能有不同的优先级:Prolog的剪切规则允许表示否定,只要查询是可判定的;
  3. 规则可能存在冲突:再次,如果满足更高优先级的目标,您可以确保不应用较低优先级的条款。有几种方法可以做到这一点。
  4. 规则是对称的:通过剪切,可以轻松确保可判定的谓词。
  5. 规则(或更确切地说是子集)可能有与之关联的元规则(明确定义):您的示例似乎暗示这相当于4,所以我不确定我在此之后得到的是什么。
  6. SLD解算器优于基于描述逻辑的工具的优点和缺点是:

    1. 程序化功能,灵活性:您通常可以找到建模难点的编程解决方案,其中描述逻辑可能需要您重新考虑模型。但当然没有管道胶带意味着描述逻辑解决方案迫使你保持清洁,这可能是一个很好的学科。
    2. 健壮性:SLD求解器是一种非常容易理解的技术,而描述逻辑工具从博士论文的出生开始往往没有多少步骤。
    3. 缺少语义工具:描述逻辑与一阶逻辑和模型逻辑有很好的联系,并为您提供了一套非常丰富的技术来推理它们。 Prolog的灵活性通常会使这非常困难。
    4. 如果您在描述逻辑方面没有特殊的专业知识,我建议使用SLD求解器。

答案 1 :(得分:2)

对于你所描述的情况,我认为你会想要使用向后链接,而不是正向链接(像Drools这样的RETE系统是正向链接,默认行为)。

结帐tuProlog。易于与Java,100%纯Java绑定,并且绝对可以进行您想要的推理。您需要充分了解Prolog以表征您的规则集。

Prova也可以进行推理和处理复杂的规则系统。

答案 2 :(得分:0)

这听起来像描述逻辑和知识基础对我来说。你有概念,角色和个体。

如果您想将问题推广为基于描述逻辑的推理,那么您应该很好地建模问题并在其上执行推理。

有一些免费的reasoners可用,可以找到一个列表here

但请注意,这是一种复杂但功能强大的方法。

使用Java时,您可能希望特别关注KAON2DIG

答案 3 :(得分:0)

我相信你可以使用ID3 algorithm来从对象的初始状态中提取一组规则。我不知道任何具体的Java实现,虽然维基百科指出从Ruby到C的不同实现(我不能发布多个超链接:-)),但它不是一个难以学习的算法。

一旦构建决策树,可以用规则格式表示,你可以使用它来查看你的对象属于哪个类:来自美国的所有男性,以及10到20岁之间的所有女性,...和当有人更新数据库中的对象时,您可以重建决策树。

答案 4 :(得分:0)

好的,这可能是一个愚蠢的答案。但无论如何我会尝试.... 你可以使用BeanShell来做这样的事情:

  • 创建一个简单的选择器命令(类似于select(inicialSet,paramName,paramValue)),它返回一个inicialSet中的set元素并匹配你的params。

  • 创建一些可以帮助您编写好的BeanShell脚本的常量。

这样您就可以将规则编写为简单的脚本和嵌套规则。

所以,这个

我需要规则的结合。因此,当提出“包括所有男性”和“排除10-20岁年龄组中的所有美国人”时,我只对美国以外的男性以及美国境内10岁以外的男性感兴趣 - 20岁年龄组。

将成为这样的脚本:

originalSet = getOriginalSet(); //Get all from DB

//elements in originalSet that have gender=male
males = select(originalSet, PARAM.GENDER, GENDER.MALE);

//elements in males that have age in [10,20]
youngMaleGuys = select(males, PARAM.AGE, AGE.10_20);

//Exclude from
males.removeAll(youngMaleGuys);

notYoungUSMaleGuys = select(males, PARAM.COUNTRY, COUNTRY.US);

males.removeAll(notYoungUSMaleGuys);

return resp;

当然,这很糟糕。我现在做了。但是你可以编写非常好的命令并找到一种方法来使它更具可读性。

不是那么快,但很容易保持和阅读(我认为)。而且你不必担心订购

多数民众赞成。我试过了。 :)

答案 5 :(得分:0)

最强大的基于Java的生产规则引擎之一(推理引擎)是JBoss DROOLS。

http://jboss.org/drools

我会说实话,除非你的应用程序变得更复杂,否则使用规则引擎是过分杀戮。另一方面,如果您的应用程序变得太大并且有太多冲突的规则,那么它将无法提供结果。

如果您可以更好地控制您的客户或问题域,最好完全避免使用推理引擎。