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

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

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

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

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

  3. 规则可能是矛盾的。因此,我可以既有“包括所有男性”,又可以将所有男性排除在外,在这种情况下,优先事项将不得不解决这个问题。

  4. 规则是对称的。因此,“包括所有男性”等同于“排除所有女性”。

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

我可以在没有项目5的情况下活下来,但是我确实需要提到的所有其他属性。我的规则和对象都存储在数据库中,并且可以在任何阶段进行更新,因此我需要在需要时实例化“推理引擎”,然后将其销毁。

有帮助吗?

解决方案

Java有一堆嵌入式序言式的SLD求解器;我最喜欢的方法是使用 Scala的迷你kanren, ,因为这很干净,并且允许您使用Scala懒惰地处理查询结果,但我没有深入使用它。看 Java的嵌入式Prolog口译/编译器 对于其他选项,以及罗斯的答案。

SLD求解器处理您的所有标准,只要它们具有Prolog具有的一些额外功能:

  1. 规则的结合:基本SLD目标处理;
  2. 规则可能具有不同的优先级:Prolog的削减规则可以代表否定,只要查询是可决定的;
  3. 规则可能是矛盾的:同样,如果满足更高的优先级目标,则可以确保不应用较低的优先级子句。有几种方法可以做到这一点。
  4. 规则是对称的:剪切,这很容易确保可确定的谓词。
  5. 规则(或更确切地说的子集)可能具有与之关联的元规则(明确定义):您的示例似乎表明这相当于4,因此我不确定我在这里得到了您的想法。

SLD求解器的优势和缺点以说明基于逻辑的工具是:

  1. 程序化功率,灵活性:您通常可以找到建模困难的编程解决方案,其中描述逻辑可能需要您重新考虑模型。但是当然,没有管道录像带意味着描述逻辑解决方案迫使您保持清洁,这可能是一门很好的纪律。
  2. 鲁棒性:SLD求解器是一项非常了解的技术,而描述逻辑工具通常比博士学位论文出生的步骤不多。
  3. 缺乏语义工具:描述逻辑与一阶逻辑和模型逻辑具有良好的链接,并为您提供了非常丰富的技术来推理它们。序言的灵活性通常会非常困难。

如果您没有描述逻辑方面的特殊专业知识,我建议使用SLD求解器。

其他提示

对于您所描述的情况,我认为您要使用向后链接而不是前向链接(像drool这样的rete系统在其默认行为中都是向前链接的)。

查看 tuprolog. 。易于使用Java,100%纯Java绑定,绝对可以进行您想要的推断。您需要足够了解Prolog,以表征您的规则集。

普罗拉 还可以进行推断和处理复杂的规则系统。

这听起来像是描述逻辑和知识基础。您有概念,角色和个体。

如果您想将问题推出为说明基于逻辑的推理,则应该很好地对问题进行建模并在其上执行推理器。

有一些自由推理者可用,可以找到列表 这里.

但是请注意,这是一种相当复杂而强大的方法。

您可能想特别了解 kaon2 使用Java时。

我相信你可以使用 ID3算法 从对象的初始状态中提取一组规则。我不知道任何具体的Java实现,尽管Wikipedia指出了从Ruby到C的不同实现(我不能发布超过一个超链接:-)),但这并不是很难学习的算法。

一旦构建了决策树,可以以规则格式表达,您可以使用它来查看您的对象所属的类别:从美国的所有男性,到10到20的所有女性,以及某人更新时您的对象在数据库中,您可以重建决策树。

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

  • 创建一个简单的Selector命令(类似Select(inicialSet,paramname,paramvalue)),该命令返回inicialSet中的设置元素并匹配您的参数。

  • 创建一些可以帮助您编写漂亮Beanshell脚本的常数。

这样,您可以将规则写成简单的脚本和巢规则。

所以这

我需要规则的结合。因此,当两者都呈现“包括所有男性”和“排除10-20岁年龄段的美国所有人”时,我只对美国以外的男性以及美国境外的男性感兴趣。 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;

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

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

就是这样。我试过。 :)

JBOSS DROORS是最强大的基于Java的生产规则引擎(推理引擎)。

http://jboss.org/drools

老实说,除非您的应用程序变得更加复杂,否则使用规则引擎是过度的。另一方面,如果您的应用程序太大并且规则太多,那么它将无法提供结果。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top