Prolog环境搭建[技术学习].doc

上传人:rrsccc 文档编号:9363790 上传时间:2021-02-21 格式:DOC 页数:19 大小:246KB
返回 下载 相关 举报
Prolog环境搭建[技术学习].doc_第1页
第1页 / 共19页
Prolog环境搭建[技术学习].doc_第2页
第2页 / 共19页
Prolog环境搭建[技术学习].doc_第3页
第3页 / 共19页
Prolog环境搭建[技术学习].doc_第4页
第4页 / 共19页
亲,该文档总共19页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Prolog环境搭建[技术学习].doc》由会员分享,可在线阅读,更多相关《Prolog环境搭建[技术学习].doc(19页珍藏版)》请在三一文库上搜索。

1、互联网络1 第第 1 章章:配置开发环境配置开发环境 NOV 15TH, 2011 这道习题几乎没有代码内容,它的主要目的是让你在计算机上安装好 Prolog。你应该尽量照着说明进行操作。 安装安装 SWI-Prolog MacOS 1.找一个你最喜欢的文本编辑器。在 Mac 系统下,TextMate 也 许是最好的选择,但是它是需要花钱购买的,如果你不想买的话,可 以使用一些免费的文本编辑器比如 Kod。需要注意的是,这写编辑器 本身都是不支持 Prolog 代码高亮的,如果你想要这个功能,你需要下 载针对这些文本编辑器的插件,其中 TextMate 的插件可以在这里下 载到 TextMat

2、e Bundle 2.下载 SWI-Prolog,请选择适合你系统版本的链接。下载解压之 后双击安装包,等待一段时间以后,你的 Prolog 就安装好了。SWI- Prolog 是 Prolog 的一个实现,作者是来自阿姆斯特丹大学的 Jan, 之所以选择这个 Prolog 实现作为开发的环境,一个原因是因为它很稳 定,运行速度也算是可以,更重要的原因是它的开发文档写的很详细。 这个 Prolog 的实现不是功能最多的,但是我个人认为是最好用的,也 是最适合 Prolog 的初学者使用。 3.当你安装好 Prolog 以后,进入命令终端,输入: 互联网络2 swipl 你应当看见下图: Win

3、dows 1.第一步同样是找一个自己喜欢的文本编辑器,个人推荐 Notepad+,你可以轻易的在 Google 上搜寻到下载地址。 2.下载 SWI-Prolog,选择 Windows 的安装包,下载解压之后双 击安装包,等待一段时间以后,你的 Prolog 就安装好了。 3.与 MacOS 不同的是,在 Windows 下,你可以不必去命令行下 面输入”swipl”,你可以直接双击桌面上的快捷方式就可以打开 SWI- Prolog 了。打开以后的界面应该和 MacOS 下的界面类似。 Linux 互联网络3 我相信使用 Linux 系统的朋友应该都懂得如何安装一个小小的软件吧? 所以在这里就

4、不赘述了 Hello World! 好像在大部分的程序语言的时候,第一个要编写的程序都是“Hello World!”。虽然“Hello World”程序不能显示出 Prolog 的特性,我 在这里也姑且做一个“Hello World!”的程序吧,目的是让大家试一 下你们刚才下载的 SWI-Prolog 是否工作。 按照之前的方法进入 SWI-Prolog,在命令行下输入: writeln(Hello World!). 需要注意的是,这行代码一定要以英文中的句号”.”来结尾,Prolog 中的“.”和 C 语言中的“;”一样,都是代表一段代码的结尾。再者, Hello World!字符串一定要以

5、单引号来包裹。 如果输入正确的话,你 将看到如下输出: Hello World! true. 这里的“Hello World!”很好理解,这是我们要求程序输出的,那么 那个奇怪的“true”是哪里来的呢?请注意,在 Prolog 终端输入的时 候,没一个语句都是以“?-”这样两个字符开头的,它代表我们输入 的程序代码其实是对 Prolog 系统的一个查询(问询),一旦用户输入 互联网络4 了查询,Prolog 系统会运用它的知识库来判定这个查询是真(true)是 假(false). writeln 是 Prolog 系统自己定义的一个语句, 它的作用是向 当前的显示设备输出一个字符串并且换行,

6、 所以很显然, 这个语句是真 的, 因为 Prolog 知道有这个语句. 这就是为什么程序的最后有一个” true”. 有意思的是,因为整个过程中 Prolog 都是在试图证明这个语句 是真是假, 向屏幕输出”Hello World!”这件事实际上是执行这个语 句的”副作用”(side effect)!在 Prolog 中, 很多任务都是靠副作用来 实现的, 包括输入输出, 甚至是参数的传递. 最后,如果想要退出 SWI-Prolog,输入: halt. 同样,不要忘记最后的“.” 好了, 到这里, 这一章就算是结束, 因为这一章讲的内容很基本, 我就 不提供习题了. 下一章我们将正式开始学习

7、有关 Prolog 语言的知识! 敬请期待! 第第 2 章章:谁是谁的爸爸谁是谁的爸爸 NOV 16TH, 2011 家谱家谱 假设我们有这样一个家谱图: 互联网络5 我们现在的任务是将这个家谱图写成程序代码的形式。请打开你最喜 欢的文本编辑器,输入以下代码。 male(di). male(jianbo). female(xin). female(yuan). female(yuqing). father(jianbo,di). father(di,yuqing). mother(xin,di). mother(yuan,yuqing). grandfather(X,Y):-father(X,

8、Z),father(Z,Y). grandmother(X,Y):-mother(X,Z),father(Z,Y). daughter(X,Y):-father(X,Y),female(Y). 这段代码里面的每一行都代表一个子句(clause)。其中带有“:-”的子 句叫做规则(rule),不带有”:-“的子句叫做事实(fact)。另外,在 Prolog 里面诸如”di”和”jianbo”这类以小写英文字母开头的名称 我们称它们为原子(atom),以大写英文字母为开头的名称我们称它们 为变量,例如上面程序里面的”X”和”Y”。顾名思义,原子是常量, 互联网络6 即它的值是不可变的,而变量的值可

9、以改变。最后需要讲的是,在 Prolog 里面”,”代表逻辑关系中的”且”,我们回在后面的章节里面 看到,”;”代表逻辑关系里面的”或”。 已经被这些名称搞得头晕了?没关系,我会在之后的教程里面详细的 介绍 Prolog 的数据类型和术语,在这里,你只需有初步的了解即可。 保存上述代码到你的磁盘的某个地方,例如在 Mac 系统里,我把它存 到“/prolog/chapter2.pl”,然后依照第一章里面讲的那样,进入 SWI-Prolog。在 SWI-Prolog 里面输入如下查询: ?- consult(path/to/your/chapter2.pl). 在我的电脑里,我应该这么输入: ?

10、- consult(/prolog/chapter2.pl). 这里”consult”的意思是让 SWI-Prolog 加载你编写的程序,然后编 译它。输入完这句查询以后,敲击回车键,你应该得到如下输出: % /Users/fengdi/prolog/chapter2.pl compiled 0.00 sec, 3,816 bytes true. 如果你得到了上述的输出,那么恭喜你,你的第一个程序完成了。如 果你得到的是其他的错误的输出,请重新检查你的程序代码是否输入 正确(不过要记得,千万不要因为想要保证代码输入的不出错而直接复 互联网络7 制粘贴代码,那样的话你学不到真正的东西)。下面,让

11、我们考验一下 我们的 SWI-Prolog 现在都知道些什么。在 SWI-Prolog 里面输入下 面一个查询: grandfather(X,yuqing). 令人惊讶的事情发生了!你得到了下列输出: X = jianbo. 你的电脑告诉你,”yuqing”的祖父是”jianbo”。现在请看之前我 们编写的”chapter2.pl”程序代码,我们在程序里根本没有明确的说 明谁是谁的祖父,我们只是给了一个规则: grandfather(X,Y):-father(X,Z),father(Z,Y). 我们说,当 X 是 Z 的父亲并且 Z 是 Y 的父亲的时候,X 是 Y 的祖父。 然后我们问,yu

12、qing 的祖父是谁,Prolog 就能自动帮我们找到答案! 下面再看一个例子: parent(keyuan,jianbo). parent(jianbo,di). parent(di,yuqing). ancestor(X,Y):-parent(X,Y). ancestor(X,Y):-parent(X,Z),ancestor(Z,Y). 互联网络8 在这个例子里面,我们定义了一个回溯的规则”ancestor”,规则可 以这样解读:我们可以说 X 是 Y 的祖先基于两个条件:X 是 Y 的 parent,或者存在一个 Z,使得 X 是 Z 的 parent 并且 Z 是 Y 的祖先。 请读者

13、仔细的想一下,是不是这个道理呢?为了证明我们的程序的正 确性,我们输入一下查询: ?- ancestor(keyuan,yuqing). Prolog 会返回: true. 这证明了我们的程序是正确的,因为根据常识,keyuan 是 yuqing 的 曾祖父,所以 keyuan 是 yuqing 的祖先。 好了,今天的新内容就讲到这里,下面是一个习题,你可以自己试验 一下。 加分习题加分习题 1.试着用 Prolog 描述一下你的家谱,并且做一些简单的查询。(小 提示:在编写你的家谱的时候,你可以试着用一些新的事实,比如:” sister(your_sister,you)”“brother(y

14、our_brother,you)”等等) 互联网络9 第第 3 章章:Prolog 是如何回答问是如何回答问 题的题的 NOV 17TH, 2011 在上一章节里面,我给大家演示了一个 Prolog 特有的神奇的功能:它 能够回答你提出的问题!在这一章里面,我将简单的解释一下 Prolog 是如何能够回答你的问题的。 首先,还是自己试着把下面的程序写一 下,然后加载到 SWI-Prolog 里面。 parent(di,yuqing). parent(keyuan,jianbo). parent(jianbo,di). ancestor(X,Y):-parent(X,Y). ancestor(X

15、,Y):-parent(X,Z),ancestor(Z,Y). 然后我们问 Prolog: ?- ancestor(keyuan,yuqing). Prolog 系统会试图证明这个查询,很显然,程序会返回”true.”那么, Prolog 系统是如何找到答案的呢?当我们向 Prolog 提问” ancestor(keyuan,yuqing)”的时候,Prolog 首先会在它的知识库里 面寻找”ancestor”的定义,当然,它找到了两个”ancestor”的定 义: 互联网络10 ancestor(X,Y):-parent(X,Y). ancestor(X,Y):-parent(X,Z),an

16、cestor(Z,Y). 按照默认的规定,它会首先取第一个规则:“ancestor(X,Y):- parent(X,Y).”由于这个规则里面的 X,Y 是变量,Prolog 会给这两个 变量赋值,使得: ancestor(keyuan,yuqing) = ancestor(X,Y) 很显然,X=keyuan,Y=yuqing。之后,Prolog 会把 ancestor 换成后 面的条件: ancestor(keyuan,yuqing) = parent(keyuan,yuqing). 之后,Prolog 试图证明”parent(keyuan,yuqing)”,根据上面的程序, 很显然,这是错的

17、,会返回:”false”。那么,之后 Prolog 会怎么 办呢?记得上面说过,ancestor 有两个规则吧,我们之前根据惯例选 择了第一个规则,现在我们可以试一下第二个规则:”ancestor(X,Y): -parent(X,Z),ancestor(Z,Y).”根据这个规则,Prolog 会把” ancestor(keyuan,yuqing).”换成了: parent(keyuan,Z),ancestor(Z,yuqing). 之前 Prolog 需要证明一个式子(ancestor(keyuan,yuqing).),现在 Prolog 需要证明两个式子了。因为这两个式子中间是一个逗号,逗号

18、 的意思是”且“,所以只有当这两个式子都是”true”时候,整个的 互联网络11 查询才是”true”。首先,Prolog 会尝试第一个”parent(keyuan,Z). “它会在知识库里面找到:”parent(keyuan,jianbo)”。于是, Z=jianbo。这时候,我们之前的那两个式子变成了: parent(keyuan,jianbo),ancestor(jianbo,yuqing). 然后,Prolog 尝试证明第二个式子:”ancestor(jianbo,yuqing)”。 同样的道理,Prolog 首先找到的是:”ancestor(X,Y):-parent(X,Y)”, 于

19、是想证明”ancestor(jianbo,yuqing)”就变成了要证明” parent(jianbo,yuqing)”。很显然”parent(jianbo,yuqing)”会返回” false”。这时候,程序会试着把”ancestor(jianbo,yuqing)”替换成” parent(jianbo,Z1),ancestor(Z1,yuqing)”。要注意的是,此处我们 不用 Z 作为变量了,而是用 Z1 作为变量,这叫做变量的重命名。原 因是我们之前已经用过 Z 做变量了,为了把现在这个 Z 变量和之前的 Z 变量区别开来,我们把现在的 Z 变量重命名为 Z1。很显然,无论变 量的名字如

20、何,它都是一个变量,理论上我们可以把它赋值成任何值, 所以修改名字不会改变变量的含义。根据我们的知识库,此时 Z1 应该 等于 di。于是我们得到了两个式子: parent(jianbo,di),ancestor(di,yuqing). 把”ancestor(di,yuqing).”换成”parent(di,yuqing)”,我们得到一 个事实(fact),所以”parent(di,yuqing)”是真。 综上所述,我们其实 是用回溯的方式把”ancestor(keyuan,yuqing).”换成了: 互联网络12 parent(keyuan,jianbo),parent(jianbo,di)

21、,parent(di,yuqing) . 由于上面的三个式子都是真的,所以”ancestor(keyuan,yuqing).” 是真的。 下面这个图显示了 Prolog 是如何证明你的查询的: 互联网络13 通过这个简单的例子,我们可以得出,Prolog 通过三个方面来尝试着 证明你给的查询(query): 匹配(unifing/matching)。例如上面的” ancestor(keyuan,yuqing) = ancestor(X,Y)”,Prolog 试图从它的知 识库里面找出最符合你的查询的规则或者是事实。 变量重命名(variable renaming)。例如上面的” parent(

22、jianbo,Z1),ancestor(Z1,yuqing)”,因为在同一个查询 (query)里面已经有了”Z”,所以 Prolog 系统将重复的 Z 命名为 Z1。(事实上,在 Prolog 内部,变量根本不会用”Z”,”Z1”这样的 名字,Prolog 的编译程序的时候就已经将”Z”换成了” G132329392049”这类名字以保证名字不会重复)。 回溯(back-tracking)。这是 Prolog 最最重要的一个特性。 Prolog 是用深度优先(depth-first search)的算法来寻找答案的。当一 个规则或者是事实不符合时,Prolog 会通过回溯的方式回到之前的状

23、态,然后去尝试另外的规则或者是事实,知道你的查询(query)被证明 为止。如果所有的可能性都搜索过了,你的查询仍然不能得到证实, 那么 Prolog 会认为你的查询证实不了,返回”false”。有关回溯算 法的详细介绍你可以去网络上搜索一下。 到这里,这一章就结束了,希望你对 Prolog 程序的执行顺序有了一个 初步的了解。说实话,Prolog 的程序回溯执行方式有时候我自己都想 不明白,特别是遇到特别复杂的问题的时候。这个时候,最好的办法 互联网络14 就是拿一张纸一支笔,亲自画一下程序的回溯图,就想上面的那个图 一样,这样就能帮助你理解程序了 加分习题加分习题 1.我们有如下代码: p

24、arent(tom,bob). parent(pam,bob). parent(pam,liz). parent(pam,bob). male(tom). male(bob). female(liz). female(pam). sister(X,Y):- parent(Z,X), parent(Z,Y), female(X), X=Y. 请比照着上面的教程里面”ancestor(keyuan,yuqing)”的执行顺序图 画一个 ?-sister(liz,bob). 的执行图。(注:程序中的”X=Y”是 X 不 等于 Y 的意思) 2.(这道题有点难度哦)请看下图: 互联网络15 我们的目的

25、是要在上面表格中白色的方格(带有 LXX 标识的方格)里面 填上英文单词,可供选择的单词有: word(d,o,g). word(r,u,n). word(t,o,p). word(f,i,v,e). word(f,o,u,r). word(l,o,s,t). word(m,e,s,s). word(u,n,i,t). word(b,a,k,e,r). word(f,o,r,u,m). word(g,r,e,e,n). word(s,u,p,e,r). word(p,r,o,l,o,g). word(v,a,n,i,s,h). word(w,o,n,d,e,r). word(y,e,l,l,o

26、,w). 试着写出一个规则 solution. solution(L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L 15,L16). Posted by 泰安小码农 Nov 17th, 2011 第第 4 章章:Prolog 程序的两种意程序的两种意 义义 NOV 18TH, 2011 单词谜题单词谜题 在进行下一章之前,我想先把上一章加分习题的第二题答案给大家揭 晓一下,因为台北小码农给我反应说这一道题有点难了,连学过 Prolog 的人都不一定会做。确实,这是一道难题,但是这道题的难点 不在于程序本身逻辑上的复杂或者是用到了什么高级的语法,这

27、道题 互联网络16 的难点在于你必须要清楚地理解 Prolog 程序的意义才能得出答案。好 了,先给大家看一下答案的程序: solution(L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L 15,L16):- word(L1,L2,L3,L4,L5), word(L9,L10,L11,L12,L13,L14), word(L1,L6,L9,L15), word(L3,L7,L11), word(L5,L8,L13,L16). 以上就是这个单词谜题的答案。在编写 Prolog 程序的时候,之前有编 程基础的朋友一定要摒弃之前编程的习惯,因为像 C

28、,Java 这样的程序 语言,程序员解决问题的方式实际上是把解决问题的步骤用程序一步 一步地表示出来。换句话说,就是程序员要用程序语言告诉电脑应当 怎样一步一步地做,才能找到问题的答案。Prolog 不是这样,Prolog 程序员让程序解决一个问题时,只需要把想要得到的答案的形式表述 出来,Prolog 系统会自动帮你找答案。就像上面这个程序一样,你告 诉 Prolog 系统,答案应该是什么样子的呢?首先,我们要将 5 个单词 填入表格中,同时,单词和单词之间有可能共享同一个英文字母。所 以这儿有两个“约束”,一个约束是单词字母的个数,第二个约束是 单词里面可以出现的字字母。让我们先写水平排列

29、的两个单词: word(L1,L2,L3,L4,L5), -单词 1 word(L9,L10,L11,L12,L13,L14) -单词 2 之后,我们加上竖直的三个单词: 互联网络17 word(L1,L6,L9,L15), -单词 3 word(L3,L7,L11), -单词 4 word(L5,L8,L13,L16) -单词 5 单词 1 和单词 3 共享字母“L1”,单词 4 和单词 1 共享字母“L3”,单 词 4 和单词 2 共享字母“L12”,依次类推,我们可以把所有的约束 都写出来。这样,我们就告诉 Prolog 系统最后的答案长得什么样儿了。 有了答案的形式,Prolog 就会

30、用我之前提到的三个策略(回溯,变量重 命名,模式匹配)来找出答案。 程序的意义程序的意义 上述的程序其实昭示了 Prolog 程序的其中一个意义:陈述性意义 (declarative meaning)。Prolog 程序具有陈述性意义就在于 Prolog 都是描述的逻辑学上的一个事实或者是一个规则。例如: mother(pam,bob). 这句程序语句陈述了一个事实:pam 是 bob 的妈妈。再看: grandmother(X,Y):-mother(X,Z),father(Z,Y). 这个语句陈述的是一个规则:当 X 是 Z 的母亲并且 Z 是 Y 的父亲时, X 是 Y 的母亲。当我们在

31、Prolog 系统上输入“grandmother(X,bob)” 这样的查询时,实际上就是让 Prolog 根据自己知道的逻辑规则来试图 证明你的查询。这就是程序的陈述性意义。 互联网络18 程序的第二个意义是过程性意义。想 Java 和 C 这样的语言一样, Prolog 的程序也具有过程性意义,即解决问题的步骤。在举例子之前, 我先讲一个在 Prolog 里面常用的语句:”write”,它的作用是向显 示屏输出信息。它的参数可以是任意类型的数据,数字,字符串,甚 至一个 Prolog 的规则都可以直接被输出。另外一个语句是”nl”,它 的作用是使 Prolog 的屏幕输出换行。下面给一个程

32、序,你就能理解” write”和”nl”的作用了: write(I have a dream),nl, write(that my four little children will one day live in a nation),nl, write(where they will not be judged by the color of their skin),nl, write(but by the content of their character.),nl, write(This is form Martin Luther King). Prolog 会这样输出: I have

33、 a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character. This is form Martin Luther King true. 上面这个程序其实就揭示了 Prolog 程序的过程性意义,它告诉 Prolog 系统:要想输出上面这一段话,首先要输出I have a dream,然后换行,接着输出that my four li

34、ttle children will 互联网络19 one day live in a nation,然后换行,依次类推。它实际上是告诉 了 Prolog 系统一个解决问题的步骤。这就是程序的过程性意义。 其实,就 Prolog 本身的意义来说,编写 Prolog 程序的时候是不提倡 加入太多的过程性意义的,尽量要以描述性意义为主,因为 Prolog 本 身就是一个描述性语言。但是,程序员们在实际开发的时候发现,他 们离不开过程性意义的程序,因为现实生活中解决问题本身就是需要 步骤的,例如你想从北京到泰安,你要先从北京到天津,然后从天津 到沧州,然后从沧州到济南,最后从济南到泰安。所以,在 Prolog 里 面就不可避免的出现过程性意义为主的程序。 加分习题加分习题 1.下面我们来试着把单词谜题的答案打印的屏幕上,你要写一个规 则”print_solution“,试着把答案这样打印: 2. word1 is XXXXXX 3. word2 is XXXXXX 4. word3 is XXXXXX 5. word4 is XXXXXX 6. word5 is XXXXXX 之后,试着解释一下你写的程序的过程性意义和陈述性意义。

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

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1