知识工程T-PROLOG(3)

2019-03-16 15:06

A-B/C A-(B/C) 两者一样 X+Y/B-C (X+(Y/B))-C 两者一样 在PROLOG中,上面的算术表达式也可写为如下结构形式: +(X,* (Y,Z)) -(A,/(B,C)) -(+(X,/(Y,B)),C)

上述中算术运算符是作为函数符出现的。一般形式为:算术运算符(变元,变元)。+(X,*(Y,Z))中乘法比加法先做,因为*结构是+结构中的一个变元。对于+结构,为了+结构,为了知道它的两个变元,必须先做乘法。到底使用哪种形式表示算术表达式,由用户决定。

对于相同优先级的运算符,PROLOG采用通常的左结合规则,即A+B-C意味着(A+B)-C,8/2/2意味着(8/2)/2,算术表达式中可按需要使用圆括号。

在PROLOG中,需要使用一特殊运算符“is”来告诉PROLFOG求值算术表达式。运算符is是中级运算符,通常它取一个变量在左边,一个算术表达式在右边。is意味着对后面的算术表达式求值,因此算术表达式中的所有变量的值在求值时必须都是已知的。使用is对算术表达式求值的一般形式为:变量is算术表达式。

例如,X is A+B表示对A+B求值,若X原先是未实例化的,则现在被实例化为A+B的值。之所以用is,因为A+B也是一个普通的PROLOG结构,而PROLOG对结构一般是不求值的。例如对结构likes(john,wine)不可能求值,因为like不是一个算术运算符,因此为了对算术表达式求值,必须用求值运算is来指明。记住,A+B这样的成分只是一个通常的PROLOG结构,好象likes(john,wine)结构一样,后面将说明这一点。

下面给出两个简单的例子说明算术表达式的使用。 例1 计算国家的人口密度

1997年一些国家的人口数和面积用PROLOG表示有: pop (usa, 212). pop (china, 825). pop (india, 586). area (usa, 3609).

area (china, 3707). area(india, 1139).

因一些PROLOG系统中只能使用不太大的整数,所以用百万表示人口数的单位,即pop(C,P)表示国家C有P百万人口,用千平方英里为面积单位,即area(C,A)表示国家C有A千平方英里面积,于是,表示人口密度的规则是(人/平方英里):

density(X,Y):- pop(X,P),area(X,A),Y is P*1000/A. 规则的意思为:

“如果国家X的人口数为P百万人,且国家X的面积为A千平方英里,并且Y是P乘以1000除以A,则国家X的人口密度是Y人/平方英里。”

上例中当PROLOG做到is时,若Y是未知的,则在求值P*1000/A后让Y代表这个值(即Y被实例化这个值)。这意味在is右边的变量必须是已知的。例如:

当打入?-density (china, X).

X=222

例2 add(X, Y, Z):- Z is X+Y

这是一个加法规则,意味着Z是X加Y。 因此当你问:

?—add (2,3,4).

no ?—add(2,3,5)

yes

第一个询问因为4不是2+3,所以回答no,第二个问题5=2+3,所以回答yes,若问:

?—add(2,3,X)

X=5

从这个实例可以看出,is的作用解释为当它的左边是一个未实例化的变量时,则is的作用是把该变量实例化为is右边代表的值。若它的左边是一个已知数(包括实例化的变量),则is的作用好象等号“=”,作相等检查。统一这两种

情况,is的含义是“是”。注意,若询问?—add(X,3.5),不可期望得到X=2,因为is右边的X值未知,PROLOG将用完自由空间而告出错(Nospace left)。

习惯于传统程序设计语言的程序员必须清楚地知道,is决不是赋值。假设X已实例化为8,如果写X is X-1,由X决不会取7,X is X-1作为目标永远失败,因为8不是7,所以8 is 7失败,同样,假设Y未实例化,若连续写Y is 5,Y is 4,则Y为实例化为5,不可能是4,第二个目标Y is 4失败。

4.比较运算

在程序中经常会出现数的比较,PROLOG提供了六种常用的比较运算,并以中缀形式表示:

X=Y (X和Y代表相同数) X \\ =Y (X和Y代表不同数) X<Y (X小于Y) X>Y (X大于Y) X=<Y (X小于等于Y) X>=Y (X大于等于Y)

这里X,Y可以是整数,或者是被实例化为整数的变量。XopY可以作为目标出现在询问和(或)规则中,此时,如果A大于B,则目标A>B成功。例如若询问?—2*3>2*4,则回答no;若问?—2*3<2*4,则回答yes。XopY也可作为变元出现在结构中。

例3,判断给定的3条边是否构成等边三角形。 equilateral(X,Y,Z):- X>0, X=Y,Y=Z. 于是?—equilateral(8,8,8).

yes – –

?—equilateral(8,7,9) no – –

如果问?—equilateral(8,8,6+2). 将回答什么?回答no。

六个比较运算符在PROLOG中是作为内部谓词的,其中“=”和“\\=”不仅能用于整数间比较,也能用于其它对象的比较。

对目标X=Y(其中X和Y是任意两个项),决定X和Y是否相等的规则是: ①原子和数总是等于自身,例 atom=atom,9=9 成功 atom=atoml,1984=1985 失败。

②若X是未实例化的变量,Y是任一对象,则X=Y,总是相等,其副作用是X被实例化为Y代表的对象。例:

?—rides (john,bike)=X 成功,且X被实例化为项rides(john,bike)。 ③两个结构相等,并且仅当它们有相同的函数符和变元个数,且对应的变元都相等,例如,下面的目标成功并且X被实例化为bike。

rides(john,bike)=rides(john,X)

结构能够嵌套,如果测试嵌套结构的相等性,则需花时间逐层的测试各结构,例:

a (b,c,d(e,F,g(h,i,j)))=a(B,C,D(E,f,g(H,i,J)))成功,B,C,E,F,H和J分别被实现为b,c,e,f,h和j。

如果对两个未实例化变量进行相等性测试,将出现第②点的特殊情况,其结果是目标成功,并且两个变量成为共享。

谓词“\\=”称为不等。如果X\\=Y失败,则X=Y成功,若X=Y成功,则X\\=Y失败。

5.程序和递归性及其例子

下面从讨论PROLOG中的几个内部谓词开始,介绍程序的递归性。 (1)member谓词,它用来确定一给定的元素是否为一给定表的成员。 例如,设有表[a,b,c,d,f,h],现要知道d或e是否在表中,同LISP一样,PROLOG也是先判别这个元素是否为该表的头。若是,则该元素在表中;否则检查这个元素是否在这表的尾中(可用member本身完成)。如果这个元素是该表的尾的成员,则它是该表的元素,即:

member(X,表):—member(X,表的尾)。 因此程序如下: member(X,[X | _]).

member(X,[ _ | _]):—member(X,Y).

第一个事实是说,如果X是表的头,则X是表的成员。这里利用了无名变量“_”,因为此时我们并不关心它的尾是什么,这个事实也可写为规则:

membr(X,[Y | _]):—X=Y.

第二个规则是说,如果X是该表的尾Y的成员,则X是该表的成员,这里也用了无名变量,此时表示我们对表头不感兴趣。

上面在定义member谓词时又调用了它自己,因此member谓词是递归定义的。现在再回到一开始提的问题,d或e是否在表[a,b,c,d,f,h]中?可询问:

?—member(d,[a,b,c,d,f,h])

Yes

?—member(d,[e,b,c,d,f,h])

no

(2)append谓词。同LISP的append函数一样,用来把两个表连结成一个表。例如[a]和[b]连结成[a,b]。分两种情况:

①终结情况,当第一个表为空表时,任何表加到空表仍为那个表。 ②否则,把第一个表的尾和第二个表连结,再把第一个表的头加入连结结果的表的前面作为头。

于是append谓词的定义为: /*1*/ append ([],L,L).

/*2*/ append([x| L1],L2,[x| L3]):—append(L1,L2,L3)

当不断地递归应用上面第二个规则,第一变元将逐步减少到空表,所以终结条件最终会发生。

使用append的其它例子,如:

?—append([a,b,c],[1,2,3],[a,b,c,1,2,3]).

yes

?—append ([a,b],Result,[a,b,a,b,x,y]).

Result=[a,b,x,y]

?—append (,[a,girl],[she,is,a,girl]).


知识工程T-PROLOG(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:职务型经济犯罪疑难问题对话录

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: