我有一组带有属性和一系列规则的对象,当应用于对象集时,它们提供了这些对象的子集。为了使这更容易理解,我将提供一个具体的例子。
我的对象是人,每个人都有三个属性:原籍国,性别和年龄组(所有属性都是离散的)。我有一堆规则,比如“来自美国的所有男性”,它们与这一大型对象的子集相对应。
我正在寻找一个现有的Java“推理引擎”或类似的东西,它将能够从规则映射到一部分人,或者建议如何创建我自己的。我已阅读过规则引擎,但该术语似乎专门用于外部化业务规则的专家系统,通常不包括任何高级形式的推理。以下是我必须处理的更复杂场景的一些示例:
我需要规则的结合。因此,当提出“包括所有男性”和“排除10-20岁年龄组中的所有美国人”时,我只对美国以外的男性以及美国境内10岁以外的男性感兴趣 - 20岁年龄组。
规则可能有不同的优先级(明确定义)。因此,“排除所有男性”的规则将覆盖“包括所有美国男性”的规则。
规则可能存在冲突。所以我可以同时包括“包括所有男性”和“排除所有男性”,在这种情况下,优先事项必须解决问题。
规则是对称的。所以“包括所有男性”相当于“排除所有女性”。
规则(或更确切地说,子集)可能具有与之关联的元规则(明确定义)。必须在应用原始规则的任何情况下应用这些元规则,或者如果通过推理到达子集,则必须应用这些元规则。因此,如果将“排除美国”的元规则附加到“包括所有男性”的规则,并且我向引擎提供“排除所有女性”的规则,则应该能够推断“排除所有女性”子集相当于“包括所有男性”子集,因此另外适用“排除美国”规则。
我很可能没有第5项,但我确实需要提到所有其他属性。我的规则和对象都存储在数据库中,并且可以在任何阶段更新,因此我需要在需要时实例化“推理引擎”并在之后将其销毁。
答案 0 :(得分:3)
Java中有许多类似Prolog的嵌入式SLD求解器;我最喜欢的方法是使用mini-Kanren for Scala,因为它很干净,允许你使用Scala懒惰地处理查询结果,但我没有在任何深度使用它。有关其他选项,请参阅Embedded Prolog Interpreter/Compiler for Java,以及Ross的回答。
SLD解算器可以处理您的所有条件,前提是它们具有Prolog的一些额外功能:
SLD解算器优于基于描述逻辑的工具的优点和缺点是:
如果您在描述逻辑方面没有特殊的专业知识,我建议使用SLD求解器。
答案 1 :(得分:2)
对于你所描述的情况,我认为你会想要使用向后链接,而不是正向链接(像Drools这样的RETE系统是正向链接,默认行为)。
结帐tuProlog。易于与Java,100%纯Java绑定,并且绝对可以进行您想要的推理。您需要充分了解Prolog以表征您的规则集。
Prova也可以进行推理和处理复杂的规则系统。
答案 2 :(得分:0)
这听起来像描述逻辑和知识基础对我来说。你有概念,角色和个体。
如果您想将问题推广为基于描述逻辑的推理,那么您应该很好地建模问题并在其上执行推理。
有一些免费的reasoners可用,可以找到一个列表here。
但请注意,这是一种复杂但功能强大的方法。
答案 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。
我会说实话,除非你的应用程序变得更复杂,否则使用规则引擎是过分杀戮。另一方面,如果您的应用程序变得太大并且有太多冲突的规则,那么它将无法提供结果。
如果您可以更好地控制您的客户或问题域,最好完全避免使用推理引擎。