逻辑编程原理

通过一阶逻辑, 可定义一个子串(substr)的谓词, 该定义由以下的一组逻辑公式完成:

(1)xsubstr(x,x)

(2)xysuffix(x,yx)

(3)xyprefix(x,xy)

(4)xyz(substr(x,y)suffix(y,z)substr(x,z))

(5)xyz(substr(x,y)prefix(y,z)substr(x,z))

将这组一阶逻辑公式转化为子句标准形:

(1)substr(x,x)

(2)suffix(x,yx)

(3)prefix(x,xy)

(4)substr(x,y)suffix(y,z)substr(x,z)

(5)substr(x,y)prefix(y,z)substr(x,z)

基于谓词substr的定义, 可以尝试求解这样的问题: 求满足substr(X,aaabcc)x.

这里称substr(X,aaabcc)为目标(Goal). 求解该问题的思路是: 结合替换, 通过归结方法证否该目标的否命题。然后, 问题的解可通过相应的替换得到。

该目标的否命题是: ¬(Xsubstr(w,aaabcc))

即: X¬substr(w,aaabcc)

接下来, 以子句标准形为基础进行归结。

(6)¬substr(X,aaabcc)

(7)¬substr(X,y1) ¬suffix(y1,aabcc)

6,4,{xX,yy1,zaabcc}

(8)¬substr(X,abcc)

7,2,{xabcc,ya,y1abcc}

(9)¬substr(X,y2) ¬suffix(y2,abcc)

8,5,{xX,yy2,zabcc}

(10)¬substr(X,abc)

9,3,{xabc,yc,y2abc}

(11)

10,1,{xX,Xabc}

于是, 得到一个替换{Xabc}, 正是这个替换使得目标的否不成立。也就是说替换{Xabc}是满足目标substr(X,aaabcc)的一个解。

归结过程不是唯一的, 不同的归结过程可能带来不同的解。 事实上, 目标substr(X,aaabcc)也确实存在不同的解。

一个霍恩子句(Horn Clause)具有以下的标准形式:

AB1,B2,,Bn

霍恩子句等价于A¬B1¬B2¬¬Bn.

左边的A是头部(Head), 右边¬Bi称为身子(Body).

一个事实(Fact)是退化的霍恩子句: A.

一个数据库(Database)由若干个事实构成。

一个目标子句(Goal Clause)是另一种退化的霍恩子句: B1,B2,,Bn.

在逻辑编程中, 一个程序子句(Program Clause)就是一个霍恩子句。

运行:

其中,数据库包括事实m1和f1-f3; s1-s2和p1是程序子句。

目标等价于¬sibling(sally,X), 而子句s1等价于sibling(X,Y)¬parent_child(Z,X)¬parent_child(Z,Y). 所以目标将与s1进行合一操作, 得到替换 {sallyX,XY}

对所有子句进行替换后, 继续进行下一步合一操作

等归结完成后,可得到替换{Xmei}为所求的解。

不过,除了"mei"之外,也会得到平凡解"ting".

可通过修改sibling谓词的定义完善此程序。

在增加"\+ X=Y"后, 得到唯一解"mei".