Prolog教程 4

本文介绍了Prolog语言中的查询和模式匹配概念,通过实例展示了如何利用Prolog的解释器进行查询并理解其背后的运行机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
现在我们的游戏中已经有了一些事实,使用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定义的子句,当找到一条与目标匹配时,它就为这条子句作上记号。当用户需要更多的答案时,它就从那条作了记号的子句开始向下查询。

我们来看一个例子,用户询问:location(X,kitchen).。Prolog找到数据库中的第一条location/2子句,并与目标比较。

目标 location(X, kitchen)
子句#1 location(desk, office)

匹配失败,因为第二个参数不同,一个是kitchen,一个是office。于是Prolog继续比较第二个子句。

目标 location(X, kitchen)
子句#2 location(apple, kitchen)

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

?- location(X, kitchen).
X = apple

如果用户输入分号(;),Prolog就开始寻找其他的答案。首先它必须释放(unbinds)变量X。然后从上一次成功的位置的下一条子句开始继续搜索。这个过程叫做回溯(backtracking)。在本例中就是第三条子句。

目标 location(X, kitchen)
子句#3 location(flashlight, desk)

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

目标 location(X, kitchen)
子句#6 location(broccoli, kitchen)

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

X = broccoli ;

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

X = crackers ;

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

no

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

Prolog的目标有四个端口用来控制运行的流程:调用(call)、退出(exit)、重试(redo)以及失败(fail)。一开始使用Call端口进入目标,如果匹配成功就到了exit端口,如果失败就到了fail端口,如果用户输入分号,则又从redo端口进入目标。下图表示了目标和它的四个端口。


每个端口的功能如下:

call 开始使用目标搜寻子句。
exit 目标匹配成功,在成功的子句上作记号,并绑定变量。
redo 试图重新满足目标,首先释放变量,并从上次的记号开始搜索。
fail 表示再找不到更多的满足目标的子句了。
下面列出了调试location(X,kitchen).时的情况。括号中的数字表示当前正在考虑的子句。

?- location(X, kitchen).
CALL: - location(X, kitchen)
EXIT:(2) location(apple, kitchen)
X = apple;
REDO: location(X, kitchen)
EXIT:(6) location(broccoli, kitchen)
X = broccoli ;
REDO: location(X, kitchen)
EXIT:(7) location(crackers, kitchen)
X = crackers ;
FAIL - location(X, kitchen)
no

在Prolog的解释器中输入,

?- debug.

就可以开始调试你的程序了。

在下一章中将介绍更为复杂的查询。 
 
本书全面系统介绍Visual Prolog语言及其编程。全书共分四个部分,第一部分简短介绍Visual Prolog可视化开发环境;第二部分包括教程的第2章至第11章,教你如何学会用Visual Prolog编程;第三部分包括第12章至第16章,详细叙述Visual Prolog的预定义特性;第四部分包括第17章至第18章,完整而系统地叙述语言元素和模块化程序设计,以及与其它语言的接口。 下面是本书每一章的内容简介。 第一部分 Visual Prolog概述 第1章 Visual Prolog开发环境 描述如何将Visual Prolog安装到你的计算机上,如何使用Visual Prolog的可视化开发环境来运行本书所提供的例子,提供一个快速指南,包括创建、运行及保存你第一个Visual Prolog程序的一些步骤,解释如何应用可视化开发环境的Test Goal实用程序来运行语言教程提供的一些Visual Prolog程序的例子。 第二部分 学习Visual Prolog 第2章 Prolog基本原理 从自然语言的观点对Prolog提供一个概括地介绍,讨论如何把自然语言的语句和问题转换为Prolog的事实、规则和询问。 第3章 Visual Prolog程序结构 包括Visual Prolog的语法,Visual Prolog的程序段,用Visual Prolog进行编程。 第4章 合一与回溯 描述Visual Prolog如何求解问题,如何给变量赋值。 第5章 简单对象与复合对象 讨论声明和建立Visual Prolog中的结构。 第6章 重复与递归 解释如何应用回溯和递归编写重复性过程;还介绍了递归结构和树。 第7章 表与递归 介绍表及其递归用法,以及一般的表操作。 第8章 内部事实数据库 讨论使用Visual Prolog的事实段在运行时间对你的程序增加事实及存储全局信息。 第9章 算术与比较运算 介绍Visual Prolog内建的全部算术函数和比较函数,而且举例说明这些函数如何使用。 第10章 高级技术 控制流程分析,使用引用变量、谓词指针、二进制论域、项的转换,使用动态截断、工具及技术进行错误和信号处理,以及有效程序的编程风格。 第11章 类和对……
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值