prolog语言说明书文档格式.docx

上传人:b****4 文档编号:17082264 上传时间:2022-11-28 格式:DOCX 页数:86 大小:112.40KB
下载 相关 举报
prolog语言说明书文档格式.docx_第1页
第1页 / 共86页
prolog语言说明书文档格式.docx_第2页
第2页 / 共86页
prolog语言说明书文档格式.docx_第3页
第3页 / 共86页
prolog语言说明书文档格式.docx_第4页
第4页 / 共86页
prolog语言说明书文档格式.docx_第5页
第5页 / 共86页
点击查看更多>>
下载资源
资源描述

prolog语言说明书文档格式.docx

《prolog语言说明书文档格式.docx》由会员分享,可在线阅读,更多相关《prolog语言说明书文档格式.docx(86页珍藏版)》请在冰豆网上搜索。

prolog语言说明书文档格式.docx

很遗憾,Prolog在这些方面做得不好,或者说很差。

不过它还是提供了一些基本的方法的。

下面是上述的程序一个完整的例子。

%Thisisthesyntaxforcomments.

%MORTAL-ThefirstillustrativePrologprogram.

mortal(X):

-person(X).

person(plato).

person(aristotle).

mortal_report:

-

write('

Knownmortalsare:

'

),nl,mortal(X),

write(X),nl,

fail.

把这个程序调入Listener中,运行mortal_report.。

-mortal_report.

socrates

plato

aristotle

no

以上程序中的一些函数以后还会详细的介绍的。

最后的那个no表示没有其他的人了。

2.何处获得Prolog

当然是在网络上面!

我现在找到了两个比较好的Prolog版本:

http:

//www.visual-

顾名思义,这是一个可以制作界面的Prolog,有试用版本下载,大概20M左右。

http//

在Amzi的网页上有两种prolog可以下载:

Amzi!

16-bitLogicExplorer,1.xMB,只有Prolog的解释器,完全免费的,速度较慢。

LogicServer,5.xMB,除了有解释器外,还可以进行编译,其最大的功能是能够和其他的编程软件连接,它作为LogicServer,其他的程序(例如使用VB编写的)可以调用它的强大的逻辑推理功能。

这样你所编写的程序会即漂亮又聪明。

90天试用,过期以后不能编译,不过你可以通过修改系统时间,来使用所有功能。

而且作为服务器和其它程序连接,是没有时间限制的。

我更倾向是用Amzi的prolog,因为它的语法比visual-prolog更加简单,而且只要结合VisualBasic,同样可以制作出和visual-prolog相当的程序出来。

3.Amzi!

LogicServer简介

amzi!

logicserver有集成开发环境IDE,你可以在其中编写、调试、运行、编译程序。

它也提供命令行的形式进行运行编译。

它由下面几个部分组成:

Listener

这是prolog解释器,你只需要把源程序调入解释器就可以解释运行了。

源程序的扩展名为.pro。

Complier

Prolog编译器,它的输出是编译过的文件,扩展名为plm,输入就是源程序pro。

Linker

Prolog连接器,输入文件为plm,输出xpl文件,最终的xpl文件就是编译连接以后的最终文件。

注意,这种文件不能够直接运行的。

Runer

Prolog运行器,使用此运行器可以运行xpl文件。

它的速度比直接在Listener中解释运行要快许多。

如果使用集成环境,这些工具都可以使用菜单调用。

下面简单介绍IDE中的Listener的使用。

1选择菜单Listener/Start,打开Amzi!

Listener,出现提示符?

2选择菜单Listener/Consult...,然后选择要解释的Prolog程序,扩展名为pro,其实是文本文件。

3然后就可以输入你的询问了。

VisualBasic+Amzi!

LogicServer

amzi!

中有很详细的例子介绍如何使用VisualBasic调用Prolog。

这里只是简单的介绍一下:

如果你下载了完整的Amzi!

LogicServer,就可以找到这个目录:

samples/vb/hello,你只需要用VB打开hello.vbp,然后运行,就可以看到一个有GreetMe!

按钮的窗口,点击它,就会弹出几个窗口,如果看到GreetingsVisualBasicProgrammer,fromAmzi!

Prolog.的话,就表示一切OK,如果出现找不到hello.xpl文件的错误,你就需要把hello.frm文件打开,找到Command1_Click(),把其中的LoadLS("

hello.xpl"

)改为LoadLS(App.Path+"

\hello.xpl"

),然后再打开hello.vbp重新测试,这次应该没有问题了。

下面简单说明一下这个小系统的构成。

首先你必须有一个已经编译好的prolog文件,扩展名为xpl,在VB中你必须调用它。

由于需要和prologserver打交道,所以系统已经定义好了许多API函数,这些函数放在一个叫做amzi4.bas的文件中,此文件放在include目录下面。

所以如果你自己编写VB的应用程序,不要忘记把amzi4.bas作为一个模块调入你的工程文件。

系统还必须一个叫做amzi4.dll的动态连接库才能够运行,其实amzi4.bas就是这个amzi4.dll的调用窗口。

所有的prolog的功能都在amzi4.dll中,你要么把这个文件copy到windows/system目录下面,要么copy到和你的程序同一个目录下面。

下面再介绍一下调用logicserver的函数。

请参照hello.frm。

CallInitLS("

"

)初始化logicserver,这是第一步,必须要。

LoadLS("

XXX.xpl"

)调入编译好的xpl文件,这一步也是必须的。

CallStrLS(TermAsLong,StrAsString)把字符串Str传给Logicserver运行,就相当于你在解释器中输入的询问一样,返回这次查询的ID到Term,数据类型为Long。

GetArgLS(TermAsLong,ArgNumAsLong,BTypeAsInteger,PtrAsVariant)

这个调用获得Term的某个参数值,ArgNum指出参数的位置,即是第几个参数,BType定义参数的数据类型,Ptr就为这个参数的值。

例如如果调用CallStrLS(Term,"

friend(X,Y)"

).就是对xpl文件进行friend(X,Y).查询,假如查询的结果是:

X=tomY=jack,即查询的结果term是friend(tom,jack),在系统中term其实是一个指针,指向这个真正的项。

然后如果调用GetArgLS(Term,2,bSTR,str)就表示要获得Term的第二个参数的值,这个值用字符串表示,并且放到str中。

所以最后的结果就是str="

jack"

CallCloseLS关闭logicserver。

使用CallStrLS和GetArgLS就能够实现在VB和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

_nounderscorefirst

Nocapsfirst

使用单引号扩起来的字符集都是合法的原子。

this-hyphen-is-ok'

UpperCase'

embeddedblanks'

下面的由符号组成的也是合法的原子:

-->

++

变量和原子相似,但是开头字符四大写字母或是下划线。

X

Input_List

_4th_argument

Z56

有了这些基本的知识,我们就可以开始编写事实了。

事实通常用来储存程序所需的数据。

例如,某次商业买卖中的顾客数据。

customer/3。

(/3表示customer有三个参数)

customer('

JohnJones'

boston,good_credit).

SallySmith'

chicago,good_credit).

必须使用单引号把顾客名引起来,因为它们是由大写字母开头的,并且中间有空格。

再看一个例子,视窗系统使用事实储存不同的窗口信息。

在这个例子中参数有窗口名称和窗口的位置坐标。

window(main,2,2,20,72).

window(errors,15,40,20,78).

某个医疗专家系统可能有如下的疾病数据库。

disease(plague,infectious).{疾病(瘟疫,有传染性)}

Prolog的解释器提供了动态储存事实和规则的方法,并且也提供了访问它们的方法。

数据库的更新是通过运行‘consult’或‘reconsult’命令。

我们也可以直接在解释器中输入谓词,但是这些谓词不会被储存到硬盘上。

寻找Nani

下面我们正式开始“寻找Nani”游戏的编写。

我们从定义基本的事实开始,这些事实是本游戏的基本的数据库。

它们包括:

房间和它们的联系

物体和它们的位置

物体的属性

玩家在游戏开始时的位置

图2.1“寻找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,'

).

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(kitchen,office).

door(hall,'

door(kitchen,cellar).

door('

kitchen).

下面定义某些物体的属性,

edible(apple).

edible(crackers).

tastes_yucky(broccoli).

最后,定义手电筒(由于是晚上,玩家必须想找到手电筒,并打开它才能到那些关了灯的房间)的状态和玩家的初始位置。

turned_off(flashlight).

here(kitchen).

好了,到此你应该学会了如何使用Prolog的事实来表达数据了。

第三节简单的查询

1.简单查询

现在我们的游戏中已经有了一些事实,使用Prolog的解释器调入此程序后,我们就可以对这些事实进行查询了。

本章和下一节中的Prolog程序只包括事实,我们要学会如何对这些事实进行查询。

Prolog的查询工作是靠模式匹配完成的。

查询的模板叫做目标(goal)。

如果有某个事实与目标匹配,那么查询就成功了,Prolog的解释器会回显'

yes.'

如果没有匹配的事实,查询就失败了,解释器回显'

no.'

我们把Prolog的模式匹配工作叫做联合(unification)。

当数据库中只包括事实时,以下三个条件是使联合成功的必要条件。

目标谓词名与数据库中的某个谓词名相同。

这两个谓词的参数数目相同。

所有的参数也相同。

在介绍查询之前,让我们回顾一下上一节所编写的Prolog程序。

room(kitchen).

room(office).

location(apple,kitchen).

location(flashlight,desk).

cellar).

location(broccoli,kitchen).

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).

你看Prolog懂我们的意思呢,它知道苹果在厨房里,并且知道厨房不在苹果里。

但是下面的询问就出问题了。

-door(office,hall).

-door(hall,office).

由于我们定义的门是单方向的,结果遇到了麻烦。

在查询目标中我们还可以使用Prolog的变量。

这种变量和其他语言中的不同。

叫它逻辑变量更合适一点。

变量可以代替目标中的一些参数。

变量给联合操作带来了新的意义。

以前联合操作只有在谓词名和参数都相同时才能成功。

但是引入了变量之后,变量可以和任何的条目匹配。

当联合成功之后,变量的值将和它所匹配的条目的值相同。

这叫做变量的绑定(binding)。

当带变量的目标成功的和数据库中的事实匹配之后,Prolog将返回变量绑定的值。

由于变量可能和多个条目匹配,Prolog允许你察看其他的绑定值。

在每次Prolog的回答后输入“;

”,可以让Prolog继续查询。

下面的例子可以找到所有的房间。

“;

”是用户输入的。

-room(X).

X=kitchen;

X=office;

X=hall;

X='

;

X=cellar;

最后的no表示找不到更多的答案了。

下面我们想看看kitchen中都有些什么。

(变量以大写字母开始)

-location(Thing,kitchen).

Thing=apple;

Thing=broccoli;

Thing=crackers;

我们还可以使用两个变量来查询所有的物体及其位置。

-location(Thing,Place).

Thing=desk

Place=office;

Thing=apple

Place=kitchen;

Thing=flashlight

Place=desk;

...

2.查询的工作原理

当Prolog试图与某一个目标匹配时,例如:

location/2,它就在数据库中搜寻所有用location/2定义的子句,当找到一条与目标匹配时,它就为这条子句作上记号。

当用户需要更多的答案时,它就从那条作了记号的子句开始向下查询。

我们来看一个例子,用户询问:

location(X,kitchen).。

Prolog找到数据库中的第一条location/2子句,并与目标比较。

目标

子句#1

location(X,kitchen)

location(desk,office)

匹配失败,因为第二个参数不同,一个是kitchen,一个是office。

于是Prolog继续比较第二个子句。

子句#2

location(apple,kitchen)

这回匹配成功,而变量X的值就被绑定成了apple。

-location(X,kitchen).

X=apple

如果用户输入分号(;

),Prolog就开始寻找其他的答案。

首先它必须释放(unbinds)变量X。

然后从上一次成功的位置的下一条子句开始继续搜索。

这个过程叫做回溯(backtracking)。

在本例中就是第三条子句。

子句#3

location(flashlight,desk)

匹配失败,直到第六条子句时匹配又成功了。

子句#6

location(broccoli,kitchen)

结果变量X又被绑定为broccoli,解释器显示:

X=broccoli;

再度输入分号,X又被解放,开始新的搜索。

又找到了:

X=crackers;

这回再没有新的子句能够匹配了,于是Prolog回答no,表示最后一次搜索失败了。

要想了解Prolog的运行顺序,最好的方法就是单步调试程序,不过在此之前,还是让我们加深一下对目标的认识吧。

Error!

Unknownswitchargument.

每个端口的功能如下:

1.call开始使用目标搜寻子句。

2.exit目标匹配成功,在成功的子句上作记号,并绑定变量。

3.redo试图重新满足目标,首先释放变量,并从上次的记号开始搜索。

4.fail表示再找不到更多的满足目标的子句了。

下面列出了调试location(X,kitchen).时的情况。

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

当前位置:首页 > PPT模板 > 简洁抽象

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

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