逻辑型程序设计语言PROLOG详细教程.docx

上传人:b****7 文档编号:8871747 上传时间:2023-02-02 格式:DOCX 页数:39 大小:85.66KB
下载 相关 举报
逻辑型程序设计语言PROLOG详细教程.docx_第1页
第1页 / 共39页
逻辑型程序设计语言PROLOG详细教程.docx_第2页
第2页 / 共39页
逻辑型程序设计语言PROLOG详细教程.docx_第3页
第3页 / 共39页
逻辑型程序设计语言PROLOG详细教程.docx_第4页
第4页 / 共39页
逻辑型程序设计语言PROLOG详细教程.docx_第5页
第5页 / 共39页
点击查看更多>>
下载资源
资源描述

逻辑型程序设计语言PROLOG详细教程.docx

《逻辑型程序设计语言PROLOG详细教程.docx》由会员分享,可在线阅读,更多相关《逻辑型程序设计语言PROLOG详细教程.docx(39页珍藏版)》请在冰豆网上搜索。

逻辑型程序设计语言PROLOG详细教程.docx

逻辑型程序设计语言PROLOG详细教程

逻辑型程序设计语言PROLOG教程

2.3.1逻辑型程序设计语言PROLOG

PROLOG的语句

PROLOG语言只有三种语句,分别称为事实、规则和问题。

 

1.事实(fact)

格式:

<谓词名>(<项表>).

功能一般表示对象的性质或关系。

其中谓词名是以小写英文字母打头的字母、数字、下划线等组成的字符串,项表是以逗号隔开的项序列。

例如:

student(john).

like(mary,music).

表示“约翰是学生”和“玛丽喜欢音乐”。

2.规则(rule)

格式:

<谓词名>(<项表>):

-<谓词名>(<项表>){,<谓词名>(<项表>)}.

功能:

一般表示对象间的因果关系、蕴含关系或对应关系。

其中“:

-”号表示“if”(也可以直接写为if),其左部的谓词是规则的结论(亦称为头),右部的谓词是规则的前提(亦称为体),{}表示零次或多次重复,逗号表示and(逻辑与),即规则的形式是一个逻辑蕴含式。

例如:

bird(X):

-animal(X),has(X,feather).

grandfather(X,Y):

-father(X,Z),father(Z,Y).

第一条规则表示“如果X是动物,并且X有羽毛,则X是鸟”;第二条规则就表示“X是Y的祖父,如果存在Z,X是Z的父亲并且Z又是Y的父亲”。

3.问题(question)

格式:

?

-<谓词名>(<项表>){,<谓词名>(<项表>)}.

功能表示用户的询问,它就是程序运行的目标。

例如:

?

-student(john).

?

-like(mary,X).

2.3.2PROLOG程序

PROLOG程序一般由一组事实、规则和问题组成。

问题是程序执行的起点,称为程序的目标。

例如下面就是一个PROLOG程序。

likes(bell,sports).

likes(mary,music).

likes(mary,sports).

likes(jane,smith).

friend(john,X):

-likes(X,reading),likes(X,music).

friend(john,X):

-likes(X,sports),likes(X,music).

?

-friend(john,Y).

可以看出,这个程序中有四条事实、两条规则和一个问题。

其中事实、规则和问题都分行书写。

规则和事实可连续排列在一起,其顺序可随意安排,但同一谓词名的事实或规则必须集中排列在一起。

问题不能与规则及事实排在一起,它作为程序的目标要么单独列出,要么在程序运行时临时给出。

这个程序的事实描述了一些对象(包括人和事物)间的关系;而规则则描述了john交朋友的条件,即如果一个人喜欢读书并且喜欢音乐(或者喜欢运动和喜欢音乐),则这个人就是john的朋友(当然,这个规则也可看作是john朋友的定义);程序中的问题是“约翰的朋友是谁?

当然,PROLOG程序中的目标可以变化,也可以含有多个语句(上例中只有一个)。

如果有多个语句,则这些语句称为子目标。

例如对上面的程序,其问题也可以是

-likes(mary,X).

?

-likes(mary,music).

?

-friend(X,Y).

?

-likes(bell,sports),likes(mary,music),friend(john,X).

等等。

当然,对于不同的问题,程序运行的结果一般是不一样的。

2.3.3PROLOG程序的运行机理

PROLOG程序的运行是从目标出发,并不断进行匹配、合一、归结,有时还要回溯,直到目标被完全满足或不能满足时为止。

1.自由变量与约束变量

PROLOG中称无值的变量为自由变量,有值的变量为约束变量。

一个变量取了某值就说该变量约束于某值,或者说该变量被某值所约束,或者说该变量被某值实例化了。

2.匹配合一

两个谓词可匹配合一,是指两个谓词的名相同,参量项的个数相同,参量类型对应相同,并且对应参量项还满足下列条件之一:

(1)如果两个都是常量,则必须完全相同。

(2)如果两个都是约束变量,则两个约束值必须相同。

(3)如果其中一个是常量,一个是约束变量,则约束值与常量必须相同。

(4)至少有一个是自由变量。

例如:

下面的两个谓词

pre1("ob1","ob2",Z)

pre1("ob1",X,Y)

只有当变量X被约束为"ob2",且Y、Z的约束值相同或者至少有一个是自由变量时,它们才是匹配合一的。

3.回溯

所谓回溯,就是在程序运行期间,当某一个子目标不能满足(即谓词匹配失败)时,控制就返回到前一个已经满足的子目标(如果存在的话),并撤消其有关变量的约束值,然后再使其重新满足。

成功后,再继续满足原子目标。

如果失败的子目标前再无子目标,则控制就返回到该子目标的上一级目标(即该子目标谓词所在规则的头部)使它重新匹配。

回溯也是PROLOG的一个重要机制。

下面,我们介绍PROLOG程序的运行过程。

我们仍以上面的程序为例。

设所给的询问是

?

-friend(john,Y).(john和谁是朋友?

则求解目标为

friend(john,Y).

这时,系统对程序进行扫描,寻找能与目标谓词匹配合一的事实或规则头部。

显然,程序中前面的四条事实均不能与目标匹配,而第五个语句的左端即规则

friend(john,X):

-likes(X,reading),likes(X,music).

的头部可与目标谓词匹配合一。

但由于这个语句又是一个规则,所以其结论要成立则必须其前提全部成立。

于是,对原目标的求解就转化为对新目标

likes(X,reading),likes(X,music).

的求解。

这实际是经归结,规则头部被消去,而目标子句变为

?

-likes(X,reading),likes(X,music).

现在依次对子目标

likes(X,reading)和likes(X,music)

求解。

子目标的求解过程与主目标完全一样,也是从头对程序进行扫描,不断进行测试和匹配合一等,直到匹配成功或扫描完整个程序为止。

可以看出,对第一个子目标like(X,reading)的求解因无可匹配的事实和规则而立即失败,进而导致规则

friend(john,X):

-likes(X,reading),likes(X,music).

的整体失败。

于是,刚才的子目标

likes(X,reading)和likes(X,music)

被撤消,系统又回溯到原目标friend(john,X)。

这时,系统从该目标刚才的匹配语句处(即第五句)向下继续扫描程序中的子句,试图重新使原目标匹配,结果发现第六条语句的左部,即规则

friend(john,X):

-likes(X,sports),likes(X,music).

的头部可与目标为谓词匹配。

但由于这个语句又是一个规则,于是,这时对原目标的求解,就又转化为依次对子目标

likes(X,sports)和likes(X,music)

的求解。

这次子目标likes(X,sports)与程序中的事实立即匹配成功,且变量X被约束为bell。

于是,系统便接着求解第二个子目标。

由于变量X已被约束,所以这时第二个子目标实际上已变成了

likes(bell,music).

由于程序中不存在事实likes(bell,music),所以该目标的求解失败。

于是,系统就放弃这个子目标,并使变量X恢复为自由变量,然后回溯到第一个子目标,重新对它进行求解。

由于系统已经记住了刚才已同第一子目标谓词匹配过的事实的位置,所以重新求解时,便从下一个事实开始测试。

易见,当测试到程序中第三个事实时,第一个子目标便求解成功,且变量X被约束为mary。

这样,第二个子目标也就变成了

likes(mary,music).

再对它进行求解。

这次很快成功。

由于两个子目标都求解成功,所以,原目标friend(john,Y)也成功,且变量Y被约束为mary(由Y与X的合一关系)。

于是,系统回答:

Y=mary

程序运行结束。

上面只给出了问题的一个解。

如果需要和可能的话,系统还可把john的所有朋友都找出来。

我们把上述程序的运行过程再用示意图(图2─1)描述如下:

图2─1PROLOG程序运行机理示例

上述程序的运行是一个通过推理实现的求值过程。

我们也可以使它变为证明过程。

例如,把上述程序中的询问改为

friend(john,mary)

则系统会回答:

yes

若将询问改为:

riend(john,smith)

则系统会回答:

no

从上述程序的运行过程可以看出,PROLOG程序的执行过程是一个(归结)演绎推理过程。

其特点是:

推理方式为反向推理,控制策略是深度优先,且有回溯机制。

其具体实现方法是:

匹配子句的顺序是自上而下;子目标选择顺序是从左向右;(归结后)产生的新子目标总是插入被消去的目标处(即目标队列的左部)。

PROLOG的这种归结演绎方法被称为SLD(LinearresolutionwithSelectionfunctionforDefiniteclause)归结,或SLD反驳-消解法。

SLD归结就是PROLOG程序的运行机理,它也就是所谓的PROLOG语言的过程性语义。

2.4TurboPROLOG程序设计

2.4.1TurboPROLOG的程序结构

一个完整的TurboPROLOG(2.0版)程序一般包括常量段、领域段、数据库段、谓词段、目标段和子句段等六个部分。

各段以其相应的关键字constants、domains、database、predicates、goal和clauses开头加以标识。

另外,在程序的首部还可以设置指示编译程序执行特定任务的编译指令;在程序的任何位置都可设置注解。

总之,一个完整的TurboPROLOG(2.0版)程序的结构如下

/*<注释>*/

<编译指令>

constants

<常量说明>

domains

<域说明>

database

<数据库说明>

predicates

<谓词说明>

goal

<目标语句>

clauses

<子句集>

当然,一个程序不一定要包括上述所有段,但一个程序至少要有一个predicates段、clauses段和goal段。

在大多数情形中,还需要一个domains段,以说明表、复合结构及用户自定义的域名。

如若省略goal段,则可在程序运行时临时给出,但这仅当在开发环境中运行程序时方可给出。

若要生成一个独立的可执行文件,则在程序中必须包含goal段。

另一方面,一个程序也只能有一个goal段。

例2.3如果把上节中的程序要作为TurboPROLOG程序,则应改写为:

/*例子程序-1*/

DOMAINS

name=symbol

PREDICATES

likes(name,name).

friend(name,name)

GOAL

friend(john,Y),write(″Y=″,Y).

CLAUSES

likes(bell,sports).

likes(mary,music).

likes(mary,sports).

likes(jane,smith).

friend(john,X):

-likes(X,sports),likes(X,music).

friend(john,X):

-likes(X,reading),likes(X,music).

结合上例,我们再对上述程序结构中的几个主要段的内容和作用加以说明(其余段在后面用到时再作说明):

领域段该段说明程序谓词中所有参量项所属的领域。

领域的说明可能会出现多层说明,直到最终说明到TurboPROLOG的标准领域为止(如上例所示)。

TurboPROLOG的标准领域即标准数据类型,包括整数、实数、符号、串和符号等,其具体说明如表2.1所示。

表2.1TurboPROLOG的标准领域

谓词段:

该段说明程序中用到的谓词的名和参量项的名(但TurboPROLOG的内部谓词无须说明)。

子句段:

该段是TurboPROLOG程序的核心,程序中的所有事实和规则就放在这里,系统在试图满足程序的目标时就对它们进行操作。

目标段:

该段是放置程序目标的地方。

目标段可以只有一个目标谓词,例如上面的例子中就只有一个目标谓词;也可以含有多个目标谓词,如:

goal

readint(X),Y=X+3,write("Y=",Y).

就有三个目标谓词。

这种目标称为复合目标。

另外,一般称程序目标段中的目标为内部目标,而称在程序运行时临时给出的目标为外部目标。

2.4.2TurboPROLOG的数据与表达式

1.领域

1)标准领域

TurboPROLOG中不定义变量的类型,只说明谓词中各个项的取值域。

2)结构

结构也称复合对象,它是TurboPROLOG谓词中的一种特殊的参量项(类似于谓词逻辑中的函数)。

结构的一般形式为

<函子>(<参量表>)

其中函子及参量的标识符与谓词相同。

注意,这意味着结构中还可包含结构。

所以,复合对象可表达树形数据结构。

例如下面的谓词

likes(Tom,sports(football,basketball,table-tennis)).

中的

sports(football,basketball,table-tennis)

就是一个结构,即复合对象。

又如:

person("张华",student("西安石油学院"),address("中国","陕西","西安")).

 reading("王宏",book("人工智能技术基础教程","西安电子科技大学出版社")).

 friend(father("Li"),father("Zhao")).

这几个谓词中都有复合对象。

复合对象在程序中的说明,需分层进行。

例如,对于上面的谓词

likes(Tom,sports(football,basketball,table-tennis)).

在程序中可说明如下:

domains

name=symbol

sy=symbol

sp=sports(sy,sy,sy)

predicates

likes(name,sp)

3)表

表的一般形式是

[x1,x2,…,xn]

其中xi(i=1,2,…,n)为PROLOG的项,一般要求同一个表的元素必须属于同一领域。

不含任何元素的表称为空表,记为[]。

例如下面就是一些合法的表。

[1,2,3]

[apple,orange,banana,grape,cane]

["PROLOG","MAENS","PROGRAMMING","inlogic"]

[[a,b],[c,d],[e]]

[]

表的最大特点是其元素个数可在程序运行期间动态变化。

表的元素也可以是结构或表,且这时其元素可以属于不同领域。

例如:

name("LiMing"),age(20),sex(male),address(xian)]

[[1,2],[3,4,5],[6,7]]

都是合法的表。

后一个例子说明,表也可以嵌套。

实际上,表是一种特殊的结构。

它是递归结构的另一种表达形式。

这个结构的函数名取决于具体的PROLOG版本。

这里我们就用一个圆点来表示。

下面就是一些这样的结构及它们的表表示形式:

结构形式表形式

·(a,[])[a]

·(a,·(b,[]))[a,b]

·(a,·(b,·(c,[])))[a,b,c]

表的说明方法是在其组成元素的说明符后加一个星号*。

如:

domains

lists=string*

predicates

pl(lists)

就说明谓词pl中的项lists是一个由串string组成的表。

对于由结构组成的表,至少得分三步说明。

例如对于下面谓词p中的表

p([name("Liming"),age(20)])

则需这样说明:

domains

rec=seg*

seg=name(string);age(integer)

predicates

p(rec)

2.常量与变量

由上面的领域可知,TurboPROLOG的常量有整数、实数、字符、串、符号、结构、表和文件这八种数据类型。

同理,TurboPROLOG的变量也就有这八种取值。

另外,变量名要求必须是以大写字母或下划线开头的字母、数字和下划线序列,或者只有一个下划线。

这后一种变量称为无名变量。

3.算术表达式

TurboPROLOG提供了五种最基本的算术运算:

加、减、乘、除和取模,相应运算符号为+、-、*、/、mod。

这五种运算的顺序为:

*、/、mod优先于+、-。

同级从左到右按顺序运算,括号优先。

算术表达式的形式与数学中的形式基本一样。

例如:

数学中的算术表达式PROLOG中的算术表达式

x+yzX+Y*Z

ab-c/dA*B-C/D

umodvUmodV(表示求U除以V所得的余数)

即是说,TurboPROLOG中算术表达式采用通常数学中使用的中缀形式。

这种算术表达式为PROLOG的一种异体结构,若以PROLOG的结构形式来表示,则它们应为

+(X,*(Y,Z))

-(*(A,B),/(C,D))

mod(U,V)

所以,运算符+、-、*、/和mod实际也就是PROLOG内部定义好了的函数符。

在TurboPROLOG程序中,如果一个算术表达式中的变元全部被实例化(即被约束)的话,则这个算术表达式的值就会被求出。

求出的值可用来实例化某变量,也可用来同其他数量进行比较,用一个算术表达式的值实例化一个变量的方法是用谓词“is”或“=”来实现。

例如:

YisX+5或Y=X+5(*)

就使变量Y实例化为X+5的值(当然X也必须经已被某值实例化),可以看出,这里对变量Y的实例化方法类似于其他高级程序语言中的“赋值”,但又不同于赋值。

例如,在PROLOG中下面的式子是错误的:

X=X+1

4.关系表达式

TurboPROLOG提供了六种常用的关系运算,即小于、小于或等于、等于、大于、大于或等于和不等于,其运算符依次为

<,<=,=,>,>=,<>

TurboPROLOG的关系表达式的形式和数学中的也基本一样,例如:

数学中的关系式TurboPROLOG中的关系式

X+1≥YX+1>=Y

X≠YX<>Y

即是说,TurboPROLOG中的关系式也用中缀形式。

当然,这种关系式为TurboPROLOG中的异体原子。

若按TurboPROLOG中的原子形式来表示,则上面的两个例子为

>=(X+1,Y)和<>(X,Y)

所以上述六种关系运算符,实际上也就是TurboPROLOG内部定义好了的六个谓词。

这六个关系运算符可用来比较两个算术表达式的大小。

例如:

brother(Name1,Name2):

-person(Name1,man,Age1),

person(Name2,man,Age2),

mother(Z,Name1),mother(Z,Name2),

Age1>Age2.

需要说明的是,“=”的用法比较特殊,它既可以表示比较,也可以表示约束值,即使在同一个规则中的同一个“=”也是如此。

例如:

(例一)

p(X,Y,Z):

-Z=X+Y.

当变量X、Y、Z全部被实例化时,“=”就是比较符。

如:

对于问题

Goal:

p(3,5,8).

机器回答:

yes。

而对于

Goal:

p(3,5,7).

机器回答:

no。

即这时机器把X+Y的值,与Z的值进行比较。

(例二)

但当X,Y被实例化,为Z未被实例化时,“=”号就是约束符。

如:

Goal:

p(3,5,Z).

机器回答:

Z=8

这时,机器使Z实例化为X+Y的结果。

2.4.3输入与输出

虽然PROLOG能自动输出目标子句中的变量的值,但这种输出功能必定有限,往往不能满足实际需要;另一方面,对通常大多数的程序来说,运行时从键盘上输入有关数据或信息也是必不可少的。

为此每种具体PROLOG一般都提供专门的输入和输出谓词,供用户直接调用。

例如,下面就是TorboPROLOG的几种输入输出谓词:

(1)readln(X)。

这个谓词的功能是从键盘上读取一个字符串,然后约束给变量X。

(2)readint(X)。

这个谓词的功能是从键盘上读取一个整数,然后约束给变量X,如果键盘上打入的不是整数则该谓词失败。

(3)readreal(X)。

这个谓词的功能是从键盘上读取一个实数,然后约束给变量X,如果键盘上打入的不是实数则该谓词失败。

(4)readchar(X)。

这个谓词的功能是从键盘上读取一个字符,然后约束给变量X,如果键盘上打入的不是单个字符,则该谓词失败。

(5)write(X1,X2,… Xn)。

这个谓词的功能是把项Xi(i=1,2,…n)的值显示在屏幕上或者打印在纸上,当有某个Xi未实例化时,该谓词失败,其中的Xi可以是变量,也可以是字符串或数字。

(6)nl换行谓词。

它使后面的输出(如果有的话)另起一行。

另外,利用write的输出项"\n"也同样可起换行作用。

例如:

write("name"),nl,write("age")

与write("name","\n","age")的效果完全一样。

例2.4用上面的输入输出谓词编写一个简单的学生成绩数据库查询程序。

PREDICATES

student(integer,string,real)

grade

GOAL

grade.

CLAUSES

student(1,"张三",90.2).

student(2,"李四",95.5).

student(3,"王五",96.4).

grade:

-write("请输入姓名:

"),readln(Name),

student(-,Name,Score),

nl,write(Name,"的成绩是",Score).

grade:

-write(“对不起,找不到这个学生!

”).

grade:

-write("对不起,找不到这个学生!

").

下面是程序运行时的屏幕显示:

请输入姓名:

王五

王五的成绩是96.4。

2.4.4分支与循环

PROLOG中并无专门的分支和循环语句,但PROLOG也可实现分支和循环程序结构。

1.分支

对于通常的IF-THEN-ELSE分支结构,PROLOG可用两条同头的并列规则实现。

例如,将

IFx>0THENx:

=1

ELSEx:

=0

用PROLOG实现则是

Br:

-x>0,x=1.

Br:

-x=0.

类似地,对于多分支,可以用多条规则实现。

例如:

Br:

-x>0,x=1.

Br:

-x=0,x=0.

Br:

-x<0,x=-1.

2.循环

PROLOG可以实现计循环次数的FOR循环,也可以实现不计循环次数的DO循环。

例如下面的程序段就实现了循环,它使得write语句重复执行了三次,而打印输出了三个学生的记录。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 自我管理与提升

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1