Prolog入门教程1.docx
- 文档编号:16410836
- 上传时间:2023-07-13
- 格式:DOCX
- 页数:105
- 大小:68.65KB
Prolog入门教程1.docx
《Prolog入门教程1.docx》由会员分享,可在线阅读,更多相关《Prolog入门教程1.docx(105页珍藏版)》请在冰点文库上搜索。
Prolog入门教程1
Prolog入门教程1
2009-11-1401:
29P.M.
如果你是一位prolog的新手,希望你首先阅读这篇文章,好对prolog的全局有个了解。
在这篇文章中我会把prolog和其他的程序语言做比较,所以希望你已经具有了一定的编程水平。
什么是prolog?
prolog是ProgramminginLOGic的缩写,意思就是使用逻辑的语言编写程序。
prolog不是很高深的语言,相反,比较起其他的一些程序语言,例如c、basic等等语言,prolog是更加容易理解的语言。
如果你从来没有接触过计算机编程,那么恭喜你,你将很容易的进入prolog世界。
如果你已经是其他语言的高手,你就需要完全丢弃你原来的编程思路,否则是很难掌握prolog的。
一个例子逻辑思维在我们日常生活中比比皆是,prolog正是把这种思维用文字描述出来的计算机语言。
还是首先举个例子吧。
比如一群年轻人正在恋爱,每个人都有自己心中所追求的对象:
张学友爱王菲张学友爱周慧敏王菲爱谢廷峰周慧敏爱张学友谢廷峰爱王菲谢廷峰爱周慧敏刘德华爱周慧敏......我们说两个年轻人要互相都喜爱,他们就算是一对情侣,那么上面的谁和谁是情侣呢?
这应该算是一道最简单逻辑推理题目了,那么我们如何用prolog语言实现呢?
“张学友爱王菲”是一条已知的事实,用prolog语言来表达就是:
爱(张学友,王菲).注意1:
这里是为了阅读方便才使用汉字的,真正的prolog是不允许使用除了基本字符以外字符的,也就是说,上面的句子必须写成love(zhangxueyou,wanfei).,电脑才能够真正的理解。
注意2:
最末尾的“.”一定不能掉,它表示一个句子结束。
注意3:
上面词汇对于电脑来说并没有真正的含义,所以我们完全可以用ai(zxy,wf).来表达这个关系,更进一步,我们甚至可以用xxx(a,b).来表达,只要你自己心里清楚xxx表示爱,a表示张学友,b表示王菲就可以了。
注意4:
张学友和王菲的顺序也没有特别的规定,你完全可以把他们换个位置:
爱(王菲,张学友).只要你心里清楚它表达的意思就行了,而以后都遵循这种被爱的人在前面的顺序,就不会出错。
其他的事实我就不写了,你可以参照上面的例子自己把已知事实翻译成prolog的语句。
那么情侣的概念怎么定义呢?
也很简单!
情侣(某人甲,某人乙):
-爱(某人甲,某人乙),爱(某人乙,某人甲).:
-在prolog中表示“如果”的意思,我们使用它来定义规则。
上面这句话的意思就是,某人甲和某人乙是情侣的规则就是:
某人甲爱某人乙,并且某人乙爱某人甲。
上面用来分隔两个爱的句子的“,”表示并且的意思。
当然为了能够让电脑运行,这个句子要改为英文的:
lovers(X,Y):
-love(X,Y),love(Y,X).注意:
在prolog中以小写字符开头的字符串代表确知的事物,比如love表示爱这种关系,而zhangxueyou表示张学友。
而以大写字母开头的字符串表示未确定的事物,翻译成汉语就是某某。
完整的可运行的prolog程序如下:
(我的拼音不好,要是什么人的名字拼写错了,请原谅:
)love(zhangxueyou,wanfei).love(zhangxueyou,zouhuimin).love(wanfei,xietinfen).love(zouhuimin,zhangxueyou).love(xietinfen,wanfei).love(xietinfen,zouhuimin).love(liudehua,zouhuimin).lovers(X,Y):
-love(X,Y),love(Y,X).我们可以看出来,完整的prolog程序是有事实和规则组成的。
事实用来储存一些数据,而规则用来储存某种可以推理出来的关系。
如果把上面的程序调入prolog解释器(关于prolog解释器,在后面有介绍)然后就可以对以上的程序进行询问。
prolog解释器的提示符号为“?
-”,你只需要在在这个提示符后面输入自己的句子就可以了。
让我们来看第一个询问:
?
-love(zhangxueyou,wanfei).事实上我们的询问完全和程序中的第一条事实一样,这个询问是“是非”询问,也就是说电脑回答的答案是yes或者no。
上面的询问的含义是:
就你所知,张学友爱王菲么?
由于我们的程序中间有这样的事实,所以解释器将回答。
yes.如果我们问:
?
-love(zhangxueyou,liudehua).解释器将回答no.因为它没有发现love(zhangxueyou,liudehua).这个事实。
在询问中我们可以使用大写字母代表未知的事物,让解释器找到答案。
例如:
?
-love(zhangxueyou,X).这句话询问的是:
张学友都喜欢那些人。
解释器将给出答案:
X=wanfei;X=zouhuimin;no.注意1:
上面的两个“;”是人工输入的,当解释器找到一个答案之后,它将这个答案输出,并且等待用户的进一步输入,如果用户输入“;”,解释器将继续寻找其他的答案,如果输入的是别的符号,解释器将终止查询。
最后那个no.是因为,系统在输出了zouhuimin这个答案以后,用户输入“;”,表示还想知道其他的答案,而解释器又找不到其他的答案了,于是输出no.来终止查询。
我们再看一个例子:
?
-love(X,zouhuimin).X=zhangxueyou;X=xietinfen;X=liudehua;no.在上面的询问中,我们只涉及到对事实的查询,下面我们来看规则的用法。
?
-lovers(X,Y).X=zhangxueyouY=zouhuimin;X=wanfeiY=xietinfen;X=zouhuiminY=zhangxueyou;X=xietinfenY=wanfei;no我们看到lovers(X,Y).找出了系统中所有的恋人。
不过每对恋人被显示了两次,这是因为prolog是考虑顺序的,也就是说lovers(a,b).和lovers(b,a).并不等价。
这一点在后面的学习中,你会了解。
再看一个例子:
?
-lovers(wanfei,Y).Y=xietinfen;no询问王菲的恋人,结果是xietinfen。
呵呵,还挺聪明的。
我们看到同样是lovers,根据其参数不同,功能也不同,这也是prolog的一个大特点。
最后让我们编写一个寻找情敌的规则来结束这一节内容吧。
rival_in_love(X,Y):
-love(X,Z),not(love(Z,X)),love(Z,Y).这段程序可以理解为:
Y是X的情敌的条件是:
X喜欢Z(代表某个人),而Z不喜欢X,而Y是Z喜欢的人。
哈哈,这不正是情敌的条件嘛。
?
-rival_in_love(X,Y).X=zhangxueyouY=xietinfen;X=xietinfenY=zhangxueyou;X=liudehuaY=zhangxueyou;no好了,你自己分析一下为什么会是这样的答案吧。
为什么要prolog看完上面的例子,不知道是否提起了你对prolog的兴趣。
如果你感兴趣的话,那么让我们继续来看prolog能够做一些什么事情吧。
理论上来说使用c语言可以编制任何种类的程序,甚至连prolog语言都是使用c语言编写的。
不过对于急于开发应用程序的用户,最关心的是如何最经济最有效率的开发程序,prolog为你多提供了一个选择的余地。
prolog苁屎嫌诳⒂泄厝斯ぶ悄芊矫娴某绦颍纾鹤蚁低场⒆匀挥镅岳斫狻⒍ɡ碇っ饕约靶矶嘀橇τ蜗贰T腥嗽ぱ詐rolog将成为下一代计算机的主要语言,虽然这个梦想目前还很难实现,不过世界上已经有许多prolog的应用实例了。
你要坚信,它绝对不是那种只在实验室发挥作用的语言,之所以大多数人都不了解它,是因为它的应用范围比较特殊而已。
prolog有许多不足之处,但是这并不影响它在逻辑推理方面的强大功能,不过最好的方法是使用某种一般语言和prolog结合,一般语言完成计算、界面之类的操作,而prolog则专心实现逻辑运算的操作。
例如:
你编写一个下棋程序,用prolog来让电脑思考如何下棋,而用VisualBasic来编写界面。
我们将在以后介绍这方面的技术。
总之,prolog在许多方面将极大的减少你的编程负担,所以赶快来了解一下它吧,也许你日后遇到什么难题,可以使用prolog迎刃而解,到那个时候,你就知道今天的学习没有白费了。
prolog的特点我个人总结了prolog的以下几个特点,因为叫做特点,所以自然要和其他的语言进行比较。
1.prolog程序没有特定的运行顺序,其运行顺序是由电脑决定的,而不是编程序的人。
从这个意义上来说,prolog程序不是真正意义上的程序。
所谓程序就是按照一定的步骤运行的计算机指令,而prolog程序的运行步骤不由人来决定。
它更像一种描述型的语言,用特定的方法描述一个问题,然后由电脑自动找到这个问题的答案。
举个极端的例子,你只需要把某个数学题目告诉它,它就会自动的找到答案,而不像使用其他的语言一样,必须人工的编制出某种算法。
2.prolog程序中没有if、when、case、for这样的控制流程语句前面已经说了,程序的运行方式有电脑自己决定,当然就用不到这些控制流程的语句了。
通常情况下,程序员不需要了解程序的运行过程,只需要注重程序的描述是否全面,不过prolog也提供了一些控制流程的方法,这些方法和其他语言中的方法有很大的区别,希望你在以后的学习当中能够融会贯通。
3.prolog程序和数据高度统一在prolog程序中,是很难分清楚哪些是程序,哪些是数据的。
事实上,prolog中的所有东西都有相同的形式,也就是说数据就是程序,程序就是数据。
举一个其他语言的例子:
如果想用c语言编写一个计算某个数学表达式的程序很简单(比如:
a=2+54),因为这是一段程序。
但是如果想编写一个计算用户输入的表达式的值的程序就很困难了。
因为用户输入的是一段数据(字符串),如果想让c语言处理这个字符串,就需要很多方面的技术。
则正是因为在c语言中,程序和数据是分开的。
而在prolog就不存在这个问题,你甚至可以很轻松的编写处理其它prolog程序的程序。
4.prolog程序实际上是一个智能数据库prolog的原理就是关系数据库,它是建立在关系数据库的基础上的。
在以后的学习中你会发现它和SQL数据库查询语言有很多相似之处。
使用prolog可以很方便的处理数据。
5.强大的递归功能在其它的语言中,你也许已经接触过递归程序了。
递归是一种非常简洁的方式,它能够有效的解决许多难题。
而在prolog中,递归的功能得到了充分的体现,你甚至都会感到惊奇,递归居然又如此巨大的能力。
下一步该怎么做如果你决定下来要学习prolog了,那么请继续看这里的教程。
你要注意哦,这里是目前全球唯一的详细介绍prolog的中文网站。
1.在学习之前,希望你能够搞到比较好的prolog解释器,下一节我将就解释器进行一些讨论。
2.然后你必须熟练的掌握解释器的使用方法。
3.然后就可以开始阅读我的教程了。
4.当你学习完整个教程以后,希望你能够进入人工智能实例环节,那里有更多的、更有用的prolog编程方法,和有趣的程序。
5.如果你想使用prolog和其它的语言结合起来,编写让人瞠目结舌的又聪明、又漂亮的程序,你就应该仔细研究VB+prolog这一节。
好了,还等什么?
让我们开始吧。
探索Prolog
Prolog在英语中的意思就是ProgramminginLOGic(逻辑编程)。
它是建立在逻辑学的理论基础之上的,最初是运用于自然语言的研究领域。
然而现在它被广泛的应用在人工智能的研究中,它可以用来建造专家系统、自然语言理解、智能知识库等。
同时它对一些通常的应用程序的编写也很有帮助。
使用它能够比其他的语言更快速地开发程序,因为它的编程方法更象是使用逻辑的语言来描述程序。
从纯理论的角度来讲,Prolog是一种令人陶醉的编程语言,但是在这本书中还是着重介绍他的实际使用方法。
进入Prolog世界
和其他的语言一样,最好的学习方法是实践。
这本书将使用Prolog的解释器来向大家介绍几个具体的应用程序的编写过程。
首先你应该拥有一个Prolog的解释器,你可以在免费prolog版本中找到它。
关于解释器的使用,请参阅相关的使用说明文档,建议使用amziprolog或者swiprolog来运行本网站的程序。
逻辑编程
什么叫逻辑编程?
也许你还没有一个整体的印象,还是让我们首先来研究一个简单的例子吧。
运用经典的逻辑理论,我们可以说“所有的人(person)都属于人类(moral)”,如果用Prolog的语言来说就是“对于所有的X,只要X是一个人,它就属于人类。
”
moral(X):
-person(X).
同样,我们还可以加入一些简单的事实,比如:
苏格拉底(socrates)是一个人。
person(socrates).
有了这两条逻辑声明,Prolog就可以判断苏格拉底是不是属于人类。
在Prolog的Listener中键入如下的命令:
?
-mortal(socrates).(此句中的'?
-'是Listener的提示符,本句表示询问苏格拉底是不是属于人类。
)
Linstener将给出答案:
yes
我们还可以询问,“谁属于人类?
”
?
-mortal(X).
我们会得到如下的答案:
X=socrates
这个简单的例子显示了Prolog的一些强大的功能。
它能让程序代码更简洁、更容易编写。
在多数情况下Prolog的程序员不需要关心程序的运行流程,这些都由Prolog自动地完成了。
当然,一个完整的程序不能只包括逻辑运算部分,还必须拥有输入输出,乃至用户界面部分。
很遗憾,Prolog在这些方面做得不好,或者说很差。
不过它还是提供了一些基本的方法的。
下面是上述的程序一个完整的例子。
%Thisisthesyntaxforcomments.%MORTAL-ThefirstillustrativePrologprogrammortal(X):
-person(X).person(socrates).person(plato).person(aristotle).mortal_report:
-write('Knownmortalsare:
'),nl,mortal(X),write(X),nl,fail.
把这个程序调入Listener中,运行mortal_report.。
?
-mortal_report.
Knownmortalsare:
socrates
plato
aristotle
no
以上程序中的一些函数以后还会详细的介绍的。
最后的那个no表示没有其他的人了。
从下一章起,就开始正式介绍Prolog的编程方法了。
我将用一个实例来介绍Prolog,这是一个文字的冒险游戏,你所扮演的角色是一个三岁的小女孩,你想睡觉了,可是没有毛毯(nani)你就不能安心的睡觉。
所以你必须在那个大房子中找到你的毛毯,这就是你的任务。
这个游戏能够显示出一些Prolog的独到之处,不过Prolog的功能远不止编个简单的游戏,所以文中还将介绍一些其他的小程序。
事实(facts)
注:
斜粗体字表示Prolog的专有名词
事实(facts)是prolog中最简单的谓词(predicate)。
它和关系数据库中的记录十分相似。
在下一章中我们会把事实作为数据库来搜索。
谓词:
Prolog语言的基本组成元素,可以是一段程序、一个数据类型或者是一种关系。
它由谓词名和参数组成。
两个名称相同而参数的数目不同的谓词是不同的谓词。
事实的语法结构如下:
pred(arg1,arg2,...argN).
其中pred为谓词的名称。
arg1,...为参数,共有N个。
‘.’是所有的Prolog子句的结束符。
没有参数的谓词形式如下:
pred.
参数可以是以下四种之一:
整数(integer)
绝对值小于某一个数的正数或负数。
原子(atom)
由小写字母开头的字符串。
变量(variable)
由大写字母或下划线(_)开头。
结构(structure)
在以后的章节介绍。
不同的Prolog还增加了一些其他的数据类型,例如浮点数和字符串等。
Prolog字符集包括:
大写字母,A-Z;小写字母,a-z;数字,0-9;+-/\^,.~:
.?
#$等。
原子通常是字母和数字组成,开头的字符必须是小写字母。
例如:
hello
twoWordsTogether
x14
为了方便阅读,可以使用下划线把单词分开。
例如:
a_long_atom_name
z_23
下面的是不合法的原子,
no-embedded-hyphens
123nodigitsatbeginning
Nocapsfirst
下划线不能放在最前面
使用单引号扩起来的字符集都是合法的原子。
例如:
'this-hyphen-is-ok'
'UpperCase'
'embeddedblanks'
下面的由符号组成的也是合法的原子:
o>,++
变量和原子相似,但是开头字符四大写字母或是下划线。
例如:
X
Input_List
下划线开头的都是变量
Z56
有了这些基本的知识,我们就可以开始编写事实了。
事实通常用来储存程序所需的数据。
例如,某次商业买卖中的顾客数据。
customer/3。
(/3表示customer有三个参数)
customer('JohnJones',boston,good_credit).
customer('SallySmith',chicago,good_credit).
必须使用单引号把顾客名引起来,因为它们是由大写字母开头的,并且中间有空格。
再看一个例子,视窗系统使用事实储存不同的窗口信息。
在这个例子中参数有窗口名称和窗口的位置坐标。
window(main,2,2,20,72).
window(errors,15,40,20,78).
某个医疗专家系统可能有如下的疾病数据库。
disease(plague,infectious).{疾病(瘟疫,有传染性)}
Prolog的解释器提供了动态储存事实和规则的方法,并且也提供了访问它们的方法。
数据库的更新是通过运行‘consult’或‘reconsult’命令。
我们也可以直接在解释器中输入谓词,但是这些谓词不会被储存到硬盘上。
寻找Nani
下面我们正式开始“寻找Nani”游戏的编写。
我们从定义基本的事实开始,这些事实是本游戏的基本的数据库。
它们包括:
房间和它们的联系
物体和它们的位置
物体的属性
玩家在游戏开始时的位置
“寻找Nani”游戏的的房间格局
首先我们使用room/1谓词定义房间,一共有五条子句,它们都是事实,如图2.1。
room(kitchen).
room(office).
room(hall).
room('diningroom').
room(cellar).
我们使用具有两个参数的谓词来定义物体的位置。
第一个参数代表物体的名称,第二个参数表示物体的位置。
开始时,我们加入如下的物体。
location(desk,office).
location(apple,kitchen).
location(flashlight,desk).
location('washingmachine',cellar).
location(nani,'washingmachine').
location(broccoli,kitchen).
location(crackers,kitchen).
location(computer,office).
注意:
我们定义的那些符号,例如:
kitchen、desk等对于我们是有意义的,可是它们对于Prolog是没有任何意义的,完全可以使用任何符号来表示房间的名称。
谓词location/2的意思是“第一个参数所代表的物体位于第二个参数所代表的物体中”。
Prolog能够区别location(sink,kitchen)和location(kitchen,sink)。
因此,参数的顺序是我们定义事实时需要考虑的一个重要问题。
下面我们来表达房间的联系。
使用door/2来表示两个房间有门相连,这里遇到了一个小小的困难:
door(office,hall).
我们想要表达的意思是,office和hall之间有一个门。
可是由于Prolog能够区分door(office,hall)和door(hall,office),所以如果我们想要表达一种双向的联系,就必须把每种联系都定义一遍。
door(office,hall).
door(hall,office).
参数的顺序对定义物体的位置有帮助,可是在定义房间的联系时却带来了麻烦。
我们不得不把每个房门都定义两次!
在这一章里,只定义单向的门,以后会很好地解决此问题的。
door(office,hall).
door(kitchen,office).
door(hall,'diningroom').
door(kitchen,cellar).
door('diningroom',kitchen).
下面定义某些物体的属性,
edible(apple).
edible(crackers).
tastes_yucky(broccoli).
最后,定义手电筒(由于是晚上,玩家必须想找到手电筒,并打开它才能到那些关了灯的房间)的状态和玩家的初始位置。
turned_off(flashlight).
here(kitchen).
好了,到此你应该学会了如何使用Prolog的事实来表达数据了。
现在我们的游戏中已经有了一些事实,使用Prolog的解释器调入此程序后,我们就可以对这些事实进行查询了。
本章和下一章中的Prolog程序只包括事实,我们要学会如何对这些事实进行查询。
Prolog的查询工作是靠模式匹配完成的。
查询的模板叫做目标(goal)。
如果有某个事实与目标匹配,那么查询就成功了,Prolog的解释器会回显'yes.'。
如果没有匹配的事实,查询就失败了,解释器回显'no.'。
我们把Prolog的模式匹配工作叫做联合(unification)。
当数据库中只包括事实时,以下三个条件是使联合成功的必要条件。
目标谓词名与数据库中的某个谓词名相同。
这两个谓词的参数数目相同。
所有的参数也相同。
在介绍查询之前,让我们回顾一下上一章所编写的Prolog程序。
room(kitchen).
room(office).
room(hall).
room('diningroom').
room(cellar).
door(office,hall).
door(kitchen,office).
door(hall,'diningroom').
door(kitchen,cellar).
door('diningroom',kitchen).
location(desk,office).
location(apple,kitchen).
location(flashlight,desk).
location('washingmachine',cellar).
location
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Prolog 入门教程
![提示](https://static.bingdoc.com/images/bang_tan.gif)