prolog学习教程Prolog教程.docx
- 文档编号:13064521
- 上传时间:2023-06-10
- 格式:DOCX
- 页数:103
- 大小:69.22KB
prolog学习教程Prolog教程.docx
《prolog学习教程Prolog教程.docx》由会员分享,可在线阅读,更多相关《prolog学习教程Prolog教程.docx(103页珍藏版)》请在冰点文库上搜索。
prolog学习教程Prolog教程
Prolog教程1-序
如果你是一位prolog的新手,希望你首先阅读这篇文章,好对prolog的全局有个了解。
在这篇文章中我会把prolog和其他的程序语言做比较,所以希望你已经具有了一定的编程水平。
什么是prolog?
prolog是Programming in LOGic的缩写,意思就是使用逻辑的语言编写程序。
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。
上面的询问的含义是:
就你所知,张学友爱王菲么?
由于我们的程序中间有这样的事实,所以解释器将回答。
顶
11
∙2006-08-2710:
09
∙回复
∙
∙NOD·AID
∙7位粉丝
∙
∙
2楼
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 = zhangxueyou
Y = zouhuimin ;
X = wanfei
Y = xietinfen ;
X = zouhuimin
Y = zhangxueyou ;
X = xietinfen
Y = 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 = zhangxueyou
Y = xietinfen ;
X = xietinfen
Y = zhangxueyou ;
X = liudehua
Y = zhangxueyou ;
no
好了,你自己分析一下为什么会是这样的答案吧。
为什么要prolog
看完上面的例子,不知道是否提起了你对prolog的兴趣。
如果你感兴趣的话,那么让我们继续来看prolog能够做一些什么事情吧。
理论上来说使用c语言可以编制任何种类的程序,甚至连prolog语言都是使用c语言编写的。
不过对于急于开发应用程序的用户,最关心的是如何最经济最有效率的开发程序,prolog为你多提供了一个选择的余地。
prolog很适合于开发有关人工智能方面的程序,例如:
专家系统、自然语言理解、定理证明以及许多智力游戏。
曾经有人预言prolog将成为下一代计算机的主要语言,虽然这个梦想目前还很难实现,不过世界上已经有许多prolog的应用实例了。
你要坚信,它绝对不是那种只在实验室发挥作用的语言,之所以大多数人都不了解它,是因为它的应用范围比较特殊而已。
prolog有许多不足之处,但是这并不影响它在逻辑推理方面的强大功能,不过最好的方法是使用某种一般语言和prolog结合,一般语言完成计算、界面之类的操作,而prolog则专心实现逻辑运算的操作。
例如:
你编写一个下棋程序,用prolog来让电脑思考如何下棋,而用Visual Basic来编写界面。
我们将在以后介绍这方面的技术。
总之,prolog在许多方面将极大的减少你的编程负担,所以赶快来了解一下它吧, 也许你日后遇到什么难题,可以使用prolog迎刃而解,到那个时候,你就知道今天的学习没有白费了。
prolog的特点
我个人总结了prolog的以下几个特点,因为叫做特点,所以自然要和其他的语言进行比较。
1. prolog程序没有特定的运行顺序,其运行顺序是由电脑决定的,而不是编程序的人。
∙2006-08-2710:
09
∙回复
∙
∙NOD·AID
∙7位粉丝
∙
∙
5楼
Prolog教程3-事实
事实 (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'
'embedded blanks'
下面的由符号组成的也是合法的原子:
>,++
变量和原子相似, 但是开头字符四大写字母或是下划线。
例如:
X
Input_List
下划线开头的都是变量
Z56
有了这些基本的知识,我们就可以开始编写事实了。
事实通常用来储存程序所需的数据。
例如,某次商业买卖中的顾客数据。
customer/3。
(/3表示customer有三个参数)
customer('John Jones', boston, good_credit).
customer('Sally Smith', 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('dining room').
room(cellar).
我们使用具有两个参数的谓词来定义物体的位置。
第一个参数代表物体的名称,第二个参数表示物体的位置。
开始时,我们加入如下的物体。
location(desk, office).
location(apple, kitchen).
location(flashlight, desk).
location('washing machine', cellar).
location(nani, 'washing machine').
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, 'dining room').
door(kitchen, cellar).
door('dining room', kitchen).
下面定义某些物体的属性,
edible(apple).
edible(crackers).
tastes_yucky(broccoli).
最后,定义手电筒(由于是晚上,玩家必须想找到手电筒,并打开它才能到那些关了灯的房间)的状态和玩家的初始位置。
turned_off(flashlight).
here(kitchen).
好了,到此你应该学会了如何使用Prolog的事实来表达数据了。
∙2006-08-2710:
10
∙回复
∙
∙NOD·AID
∙7位粉丝
∙
∙
6楼
Prolog教程4-简单查询
现在我们的游戏中已经有了一些事实,使用Prolog的解释器调入此程序后,我们就可以对这些事实进行查询了。
本章和下一章中的Prolog程序只包括事实,我们要学会如何对这些事实进行查询。
Prolog的查询工作是靠模式匹配完成的。
查询的模板叫做目标(goal)。
如果有某个事实与目标匹配,那么查询就成功了,Prolog的解释器会回显'yes.'。
如果没有匹配的事实,查询就失败了,解释器回显'no.'。
我们把Prolog的模式匹配工作叫做联合(unification)。
当数据库中只包括事实时,以下三个条件是使联合成功的必要条件。
目标谓词名与数据库中的某个谓词名相同。
这两个谓词的参数数目相同。
所有的参数也相同。
在介绍查询之前,让我们回顾一下上一章所编写的Prolog程序。
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
door(office, hall).
door(kitchen, office).
door(hall, 'dining room').
door(kitchen, cellar).
door('dining room', kitchen).
location(desk, office).
location(apple, kitchen).
location(flashlight, desk).
location('washing machine', cellar).
location(nani, 'washing machine').
location(broccoli, kitchen).
location(crackers, kitchen).
location(computer, office).
edible(apple).
edible(crackers).
tastes_yucky(broccoli).
here(kitchen).
以上是我们的“寻找Nani”中的所有事实。
把这段程序调入Prolog解释器中后就可以开始进行查询了。
我们的第一个问题是:
office在本游戏中是不是一个房间。
?
-room(office). {?
-是解释器的提示符}
yes.
Prolog回答yes,因为它在数据库中找到了room(office).这个事实。
我们继续问:
有没有attic这个房间。
?
-room(attic).
no.
Prolog回答no,因为它在数据库中找不到room(attic).这个事实。
同样我们还可以进行如下的询问。
?
- location(apple, kitchen).
yes
?
- location(kitchen, apple).
no
你看Prolog懂我们的意思呢,它知道苹果在厨房里,并且知道厨房不在苹果里。
但是下面的询问就出问题了。
?
- door(office, hall).
yes
?
- door(hall, office).
no
由于我们定义的门是单方向的,结果遇到了麻烦。
在查询目标中我们还可以使用Prolog的变量。
这种变量和其他语言中的不同。
叫它逻辑变量更合适一点。
变量可以代替目标中的一些参数。
变量给联合操作带来了新的意义。
以前联合操作只有在谓词名和参数都相同时才能成功。
但是引入了变量之后,变量可以和任何的条目匹配。
当联合成功之后,变量的值将和它所匹配的条目的值相同。
这叫做变量的绑定(binding)。
当带变量的目标成功的和数据库中的事实匹配之后,Prolog将返回变量绑定的值。
由于变量可能和多个条目匹配,Prolog允许你察看其他的绑定值。
在每次Prolog的回答后输入“;”,可以让Prolog继续查询。
下面的例子可以找到所有的房间。
“;”是用户输入的。
?
- room(X).
X = kitchen ;
X = office ;
X = hall ;
X = 'dining room' ;
X = cellar ;
no
最后的no表示找不到更多的答案了。
下面我们想看看kitchen中都有些什么。
(变量以大写字母开始)
?
- location(Thing, kitchen).
Thing = apple ;
Thing = broccoli ;
Thing = crackers ;
no
我们还可以使用两个变量来查询所有的物体及其位置。
?
- location(Thing, Place).
Thing = desk
Place = office ;
Thing = apple
Place = kitchen ;
Thing = flashlight
Place = desk ;
...
no
查询的工作原理
当Prolog试图与某一个目标匹配时,例如:
location/2,它就在数据库中搜寻所有用location/2定义的子句,当找到一条与目标匹配时,它就为这条子句作上记号。
当用户需要更多的答案时,它就从那条作了记号的子句开始向下查询。
∙2006-08-2710:
10
∙回复
∙
∙NOD·AID
∙7位粉丝
∙
∙
7楼
我们来看一个例子,用户询问:
location(X,kitchen).。
Prolog找到数据库中的第一条location/2子句,并与目标比较。
目标 location(X, kitchen)
子句#1 location(desk, office)
匹配失败,因为第二个参数不同,一个是kitchen,一个是office。
于是Prolog继续比较第二个子句。
目标 location(X, kitchen)
子句#2 locati
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- prolog 学习 教程