15.1 目标 (The Aim)
在这个程序中,我们将用一种熟悉的形式来表示信息:包含单个判断式,以及跟在之后的零个或多个参数所组成的列表。要表示 Donald 是 Nancy 的家长,我们可以这样写:
(parent donald nancy)
事实上,我们的程序是要表示一些从已有的事实作出推断的规则。我们可以这样来表示规则:
(<- head body)
其中, head
是 那么…部分 (then-part), body
是 如果…部分 (if-part)。在 head
和 body
中我们使用以问号为前缀的符号来表示变量。所以下面这个规则:
(<- (child ?x ?y) (parent ?y ?x))
表示:如果 y 是 x 的家长,那么 x 是 y 的孩子;更恰当地说,我们可以通过证明 (parent y x)
来证明 (child x y)
的所表示的事实。
可以把规则中的 body 部分(if-part) 写成一个复杂的表达式,其中包含 and
, or
和 not
等逻辑操作。所以当我们想要表达 “如果 x 是 y 的家长,并且 x 是男性,那么 x 是 y 的父亲” 这样的规则,我们可以写:
(<- (father ?x ?y) (and (parent ?x ?y) (male ?x)))
一些规则可能依赖另一些规则所产生的事实。比如,我们写的第一个规则是为了证明 (child x y)
的事实。如果我们定义如下规则:
(<- (daughter ?x ?y) (and (child ?x ?y) (female ?x)))
然后使用它来证明 (daughter x y)
可能导致程序使用第一个规则去证明 (child x y)
。
表达式的证明可以回溯任意数量的规则,只要它最终结束于给出的已知事实。这个过程有时候被称为反向链接 (backward-chaining)。之所以说 反向 (backward) 是因为这一类推论先考虑 head 部分,这是为了在继续证明 body 部分之前检查规则是否有效。链接 (chaining) 来源于规则之间的依赖关系,从我们想要证明的内容到我们的已知条件组成一个链接 (尽管事实上它更像一棵树)。 λ