Artificial intelligence 规则引擎/Rete算法中是否允许使用函数符号?

Artificial intelligence 规则引擎/Rete算法中是否允许使用函数符号?,artificial-intelligence,rule-engine,first-order-logic,rete,Artificial Intelligence,Rule Engine,First Order Logic,Rete,在讨论中的推理时提出 然而,我发现的所有关于Rete算法的描述似乎都使用了没有函数符号的规则。 换句话说,规则看起来像 a(X) ∧ b(X, Y) → c(Y) 但不是 a(f(X)) ∧ b(X, Y) → c(f(Y)) (区别可能是根本性的,因为它是Prolog和Datalog之间的区别,其中只有一个是图灵完成的) Rete算法是否仅限于没有函数符号的规则? 像Drools和CLIPS这样的现代规则引擎处理功能符号吗?在CLIPS中,这就是你如何实现规则“对于每个人来说,都有一个而且

在讨论中的推理时提出

然而,我发现的所有关于Rete算法的描述似乎都使用了没有函数符号的规则。 换句话说,规则看起来像

a(X) ∧ b(X, Y) → c(Y)
但不是

a(f(X)) ∧ b(X, Y) → c(f(Y))
(区别可能是根本性的,因为它是Prolog和Datalog之间的区别,其中只有一个是图灵完成的)

Rete算法是否仅限于没有函数符号的规则?
像Drools和CLIPS这样的现代规则引擎处理功能符号吗?

在CLIPS中,这就是你如何实现规则“对于每个人来说,都有一个而且只有一个父亲,如果一个人的父亲很富有,那么他/她也很富有”:


您的示例的问题是Drools对Java对象有效。通过将
father
变量定义为一个实例而不是列表来处理条件“每个人只有一个父亲”的问题。这将检查简化为空检查

在Drools中,您将如何实现这个简单的英语用例:

对于每个人来说,都有并且只有一个父亲,如果一个人的父亲很富有,那么他/她也是

这条规则的右侧(结果)将触发每个有钱人和父亲有钱的人。开头的
not
子句验证工作内存中的所有Person实例都具有父实例。每个进入工作记忆的人都会根据各自的优点进行评估,即使有多人进入

基本上你是这样理解的:“所有的人都有一个父亲。每个富人都有一个富有的父亲。”如果你改变物体的设计,检查孩子,你可以断言“如果一个人富有,那么所有的孩子都富有”

为完整起见,此处建模的Java类如下所示:

public class Person {
  private Person father;
  private boolean isRich;
  public Person getFather() { return this.father; }
  public Person getIsRich() { return this.isRich; }
  // Setter methods omitted for brevity
}

当然,如果您尝试测试不符合此条件的情况,您当然可以将其反转:

rule "A person exists without a father"
when
  exists( Person( father == null) )
then
  // Do something for situation if there's a father-less person
end

rule "A person is rich and their father is not rich"
when
  Person( $father: father != null, 
                   isRich == true )
  Person( isRich == false ) from $father
then
  // Do something for the poor father
end
。。。当然,您可以将它们组合成一个规则,但这被认为是糟糕的规则设计

Drools是一种商业规则语言。它用于条件和结果的组合——“如果这些条件是真的,那么就这样做”。您的场景是一个简单的语句,而不是条件+结果,因此在这里建模有点困难,因为它缺少结果


但是,它确实有隐式应用于每个输入的好处,而不必指定循环或递归函数。调用上述(正面和负面案例)的方法是创建一个Person实例集合,并将它们一次全部传递到会话中。Drools将根据输入值对每个人实例的优点进行评估。在评估规则是否有效时,在不调用特殊Drools“刷新”功能(
update
insert
modify
retract
)的情况下对这些实例所做的任何更改都将被忽略。例如,如果我传入一个没有父亲的人的例子,然后在我的一条规则中添加一个人,从“when”子句的角度来看,我的人仍然没有父亲;除非我使用上述函数特别通知Drools,否则将根据无误输入评估规则。

如果我正确理解您的符号,则是的,Drools引擎允许在条件和后果范围内进行功能评估。不过,我不能为其他引擎说话。对其他引擎也是如此CLIPS@RoddyoftheFrozenPeas逻辑中的“函数符号”可能与其他地方的“函数”不同。这里有一个试金石测试:当你陈述规则时,你能用一个逻辑变量作为那些“函数”的参数吗?(见Q中的第二个例子)@GaryRiley请看我对Roddy的回复。@MaxB我刚才提到Prolog是因为你提到了。如果没有简单的方法来解释函数arg或者为什么要使用它们,那么有人很难回答您的问题。您的示例无法说明函数arg的作用。规则应该说明“每个人都有一个父亲,而且只有一个父亲……”。相反,你把他的存在作为一个条件。在您的解释中,
father
字段永远不应为空。Drools不能无条件地陈述它吗?在一个充满条件和后果的世界里,什么是陈述?我把它当作一种疾病来对待。因为一个陈述可以是真的,也可以是假的,所以它似乎是一种合适的建模方法。如果该语句为true,则该规则将求值;如果该语句为false,则不会(除非您反转条件)。Drools是一种业务规则语言。它不用于对抽象逻辑结构进行建模。如果您有温度传感器,并且声明“如果任何传感器连续3分钟报告>120度,则打开火警”。。。我们可以用口水来做。如果你把富人/穷人的例子当作一个有条件的例子来处理,那么这个例子就可以翻译一半。但是你的规则关心你是否想知道它是真是假,这将改变你编写规则的方式。实际上有两条规则。第一种情况(“对于每个人来说,存在一位且只有一位父亲”)需要说明存在。我在您的代码中看不到它。这就是forall语句所做的。为什么您甚至需要forall?即使没有对所有规则进行包装,这条规则也会以同样的方式执行,不是吗?@Akaedintov不,不会的。这个forall是(not(person?p)(not(and(father?p?f)(not(father?p~?f)))的简写形式。有必要保证每个人都有一个且只有一个父亲。
public class Person {
  private Person father;
  private boolean isRich;
  public Person getFather() { return this.father; }
  public Person getIsRich() { return this.isRich; }
  // Setter methods omitted for brevity
}
rule "A person exists without a father"
when
  exists( Person( father == null) )
then
  // Do something for situation if there's a father-less person
end

rule "A person is rich and their father is not rich"
when
  Person( $father: father != null, 
                   isRich == true )
  Person( isRich == false ) from $father
then
  // Do something for the poor father
end