笨方法学prolog(转)
prolog吧
全部回复
仅看楼主
level 7
http://fengdidi.github.io/blog/archives/
前言
我一直以来想写一部帮助想学Prolog的朋友学习Prolog的教程,因为我在学习Prolog的过程中,发现有关Prolog的教学文档很少很少,中文的文档更是几乎没有。这给我学习Prolog带来很大的困难,基本上都是在一边摸索一边学习的。所以我幻想着有一天能够写一篇Prolog的入门教程,来帮助其他想学Prolog的朋友对其有一个初步的了解。 这个想法在我心里存在了很久了,但是一直却没有付诸实施。其原因一是我没有太多的时间写这些文章,二是我没有一个如何写这部教程的点子。
直到台北小码农同学给我推荐了一个系列的教程叫《Learn XXX The Hard Way》,并且邀请我一起来仿照着写Prolog和Scheme的教程。我大致的阅读了一下《Learn Python The Hard Way》,发现那本书很适合对计算机了解不多,没有学过编程,但对编程感兴趣的朋友学习使用。那本书以习题的方式引导读者一步一步学习编程,从简单的打印一直讲到完整项目的实现。也许读完那本书并不意味着读者已经学会了编程,但至少读者会对编程语言以及编程这个行业有一个初步的了解。所以,我决定接受台北小码农的提议,仿照着这种格式来写一篇关于Prolog的入门教程。
这部教程假设读者有一定的英文基础,却不需要读者有半点的编程基础,反而,之前有过编程基础的朋友反而会发现学习起来有一定的吃力,因为Prolog的思考方式和其他的程序语言完全不同,所以你在写程序的时候需要时时刻刻地转换你的思维。
在学习这部教程的时候,你一定要记得一个道理,就是“万事开头难”。做事一定要不怕困难,要坚持,半途而废的话就永远不会成功。我本人就是一个喜欢半途而废的人,通常做一件事,每次都是想的比做的多,通常遇到一点儿困难以后就放弃了。所以我一直都没有成功。所以我在这里本着对我的读者负责的态度,一定要坚持把这部教程写完,这样我就总算是坚持做完了一件事。希望大家监督我哦~
既然我都开始坚持做完一件事了,优秀的你,一定要不管是什么原因,一定坚持下去。如果你碰到做不出来的加分习题,或者碰到一节看不懂的习题,你可以暂时跳过去,过一阵子回来再看。只要坚持下去,你总会弄懂的。
一开始你可能什么都看不懂。这会让你感觉很不舒服,就像学习人类的自然语言一样。你会发现很难记住一些单词和特殊符号的用法,而且会经常感到很迷茫,直到有一天,忽然一下子你会觉得豁然开朗,以前不明白的东西忽然就明白了。如果你坚持练习下去,坚持去上下求索,你最终会学会这些东西的。也许你不会成为一个编程大师,但你至少会明白程序是怎么工作的。
如果你通读了这部教程,却还是不知道编程是怎么回事。那也没关系,至少你尝试过了。你可以说你已经尽过力但成效不佳,但至少你尝试过了。这也是一件值得你骄傲的事情。
许可协议
你可以在不收取任何费用,而且不修改任何内容的前提下自由分发这本书给任何人。但是本书的内容只允许完整原封不动地进行分发和传播。
2014年07月14日 01点07分 1
level 7
第1章:配置开发环境
这道习题几乎没有代码内容,它的主要目的是让你在计算机上安装好Prolog。你应该尽量照着说明进行操作。
安装SWI-PrologMacOS
找一个你最喜欢的文本编辑器。在Mac系统下,TextMate也许是最好的选择,但是它是需要花钱购买的,如果你不想买的话,可以使用一些免费的文本编辑器比如Kod。需要注意的是,这写编辑器本身都是不支持Prolog代码高亮的,如果你想要这个功能,你需要下载针对这些文本编辑器的插件,其中TextMate的插件可以在这里下载到TextMate Bundle
下载SWI-Prolog,请选择适合你系统版本的链接。下载解压之后双击安装包,等待一段时间以后,你的Prolog就安装好了。SWI-Prolog是Prolog的一个实现,作者是来自阿姆斯特丹大学的Jan,之所以选择这个Prolog实现作为开发的环境,一个原因是因为它很稳定,运行速度也算是可以,更重要的原因是它的开发文档写的很详细。这个Prolog的实现不是功能最多的,但是我个人认为是最好用的,也是最适合Prolog的初学者使用。
当你安装好Prolog以后,进入命令终端,输入:swipl你应当看见下图:
Windows
第一步同样是找一个自己喜欢的文本编辑器,个人推荐Notepad++,你可以轻易的在Google上搜寻到下载地址。
下载SWI-Prolog,选择Windows的安装包,下载解压之后双击安装包,等待一段时间以后,你的Prolog就安装好了。
与MacOS不同的是,在Windows下,你可以不必去命令行下面输入”swipl”,你可以直接双击桌面上的快捷方式就可以打开SWI-Prolog了。打开以后的界面应该和MacOS下的界面类似。
Linux
我相信使用Linux系统的朋友应该都懂得如何安装一个小小的软件吧?所以在这里就不赘述了~
Hello World!
好像在大部分的程序语言的时候,第一个要编写的程序都是“Hello World!”。虽然“Hello World”程序不能显示出Prolog的特性,我在这里也姑且做一个“Hello World!”的程序吧,目的是让大家试一下你们刚才下载的SWI-Prolog是否工作。
按照之前的方法进入SWI-Prolog,在命令行下输入:
writeln('Hello World!').
需要注意的是,这行代码一定要以英文中的句号”.”来结尾,Prolog中的“.”和C语言中的“;”一样,都是代表一段代码的结尾。再者,Hello World!字符串一定要以单引号来包裹。 如果输入
正确的
话,你将看到如下输出:
Hello World!true.
这里的“Hello World!”很好理解,这是我们要求程序输出的,那么那个奇怪的“true”是哪里来的呢?请注意,在Prolog终端输入的时候,没一个语句都是以“?-”这样两个字符开头的,它代表我们输入的程序代码其实是对Prolog系统的一个查询(问询),一旦用户输入了查询,Prolog系统会运用它的知识库来判定这个查询是真(true)是假(false). writeln是Prolog系统自己定义的一个语句, 它的作用是向当前的显示设备输出一个字符串并且换行, 所以很显然, 这个语句是真的, 因为Prolog知道有这个语句. 这就是为什么程序的最后有一个”true”. 有意思的是,因为整个过程中Prolog都是在试图证明这个语句是真是假, 向屏幕输出”Hello World!”这件事实际上是执行这个语句的”副作用”(side effect)!在Prolog中, 很多任务都是靠副作用来实现的, 包括输入输出, 甚至是参数的传递.
最后,如果想要退出SWI-Prolog,输入:
halt.
同样,不要忘记最后的“.”~
好了, 到这里, 这一章就算是结束, 因为这一章讲的内容很基本, 我就不提供习题了. 下一章我们将正式开始学习有关Prolog语言的知识! 敬请期待!
2014年07月14日 01点07分 2

2014年07月15日 04点07分
顶楼,同学习SWI-prolog找不到学习资料[乖]
2016年12月23日 07点12分
在哪里下载 swi prolog啊 麻烦告诉下
2017年03月02日 15点03分
@Stoppp▫ 百度搜索swi prolog 第一个页面-SWI-Prolog downloads- Stable release
2017年03月03日 04点03分
level 7
第2章:谁是谁的爸爸
家谱
假设我们有这样一个家谱图:
我们现在的任务是将这个家谱图写成程序代码的形式。请打开你最喜欢的文本编辑器,输入以下代码。
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,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”。顾名思义,原子是常量,即它的值是不可变的,而变量的值可以改变。最后需要讲的是,在Prolog里面”,”代表逻辑关系中的”且”,我们回在后面的章节里面看到,”;”代表逻辑关系里面的”或”。
已经被这些名称搞得头晕了?没关系,我会在之后的教程里面详细的介绍Prolog的数据类型和术语,在这里,你只需有初步的了解即可。
保存上述代码到你的磁盘的某个地方,例如在Mac系统里,我把它存到“~/prolog/chapter2.pl”,然后依照第一章里面讲的那样,进入SWI-Prolog。在SWI-Prolog里面输入如下查询:
?- consult('path/to/your/chapter2.pl').
在我的电脑里,我应该这么输入:
?- consult('~/prolog/chapter2.pl').
这里”consult”的意思是让SWI-Prolog加载你编写的程序,然后编译它。输入完这句查询以后,敲击回车键,你应该得到如下输出:
% /Users/fengdi/prolog/chapter2.pl compiled 0.00 sec, 3,816 bytestrue.
如果你得到了上述的输出,那么恭喜你,你的第一个程序完成了。如果你得到的是其他的错误的输出,请重新检查你的程序代码是否输入正确(不过要记得,千万不要因为想要保证代码输入的不出错而直接复制粘贴代码,那样的话你学不到真正的东西)。下面,让我们考验一下我们的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的祖父。然后我们问,yuqing的祖父是谁,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).
在这个例子里面,我们定义了一个回溯的规则”ancestor”,规则可以这样解读:我们可以说X是Y的祖先基于两个条件:X是Y的parent,或者存在一个Z,使得X是Z的parent并且Z是Y的祖先。请读者仔细的想一下,是不是这个道理呢?为了证明我们的程序的正确性,我们输入一下查询:
?- ancestor(keyuan,yuqing).
Prolog会返回:
true.
这证明了我们的程序是正确的,因为根据常识,keyuan是yuqing的曾祖父,所以keyuan是yuqing的祖先。
好了,今天的新内容就讲到这里,下面是一个习题,你可以自己试验一下。
加分习题
试着用Prolog描述一下你的家谱,并且做一些简单的查询。(小提示:在编写你的家谱的时候,你可以试着用一些新的事实,比如:”sister(your_sister,you)”“brother(your_brother,you)”等等)
2014年07月14日 01点07分 3
parent(keyuan,jianbo).parent(jianbo,di).parent(di,yuqing).ancestor(X,Y):-parent(X,Y).ancestor(X,Y):-parent(X,Z),ancestor(Z,Y).这个例子我运行的时候“ancestor(keyuan,yuqing)."是输出false
2014年09月08日 12点09分
我输入的时候显示:Arguments are not sufficiently instantiated。没有足够的实例
2015年06月30日 12点06分
@各种求发展 我也是
2016年01月10日 16点01分
Operator expected 、 说明:汇编程序需要的是操作符,得到的却是其它内容
2016年12月19日 12点12分
level 7
这样
print_solution:-
solution(L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L15,L16),
write('word1 is '),write(L1),write(L2),write(L3),write(L4),write(L5),nl,
write('word2 is '),write(L9),write(L10),write(L11),write(L12),write(L13),write(L14),nl,
write('word3 is '),write(L1),write(L6),write(L9),write(L15),nl,
write('word4 is '),write(L3),write(L7),write(L11),nl,
write('word5 is '),write(L5),write(L8),write(L13),write(L16),nl.
原文定义的结构比较麻烦。按它的思路就应该这样写
2014年07月15日 10点07分 6
level 5
很好的资料,可以太监了
2014年07月16日 06点07分 7
可惜,打错字了……
2014年07月16日 06点07分
原来是被你阉割的[汗]
2015年04月11日 05点04分
level 8
顶个![大拇指]
2014年09月10日 01点09分 8
level 5
太监好久了
2014年12月18日 12点12分 9
level 6
=_=
2014年12月24日 16点12分 10
level 6
[冷]。。。没了
2015年01月26日 17点01分 11
level 1
作者太懒了吧。。。
2015年04月11日 05点04分 12
level 7
怎么突然没了
2015年05月18日 12点05分 13
level 1
楼主更新啊
2015年11月09日 11点11分 14
level 1
tj了?
2016年11月30日 12点11分 16
level 2
楼楼好强啊~虚心学习
2016年12月06日 06点12分 17
level 2
玩人工智能逻辑程序[大拇指]
2017年01月13日 00点01分 18
level 13
这篇文章的确是太监了
2017年11月19日 11点11分 19
level 9
“...一直以来想写一部帮助想学Prolog的朋友学习Prolog的教程,因为我在学习Prolog的过程中,发现有关Prolog的教学文档很少很少,中文的文档更是几乎没有。这给我学习Prolog带来很大的困难,基本上都是在一边摸索一边学习的” ------- 非常同感!学习中....
能够介绍一些怎样在swiprolog中实现下面这些功能吗?
1 文件的读取和写入;
2 窗口界面的设计和菜单设计;
3 怎样调用C库或更多的三方库包;
4 能否连接数据库,比如mysql。
谢谢![]
2017年12月02日 03点12分 20
我写过一篇百度经验:https://jingyan.baidu.com/article/da1091fb743244027949d654.html是关于文件的读写的(在经验的后半部分),不过写得很简略了。[委屈]调用第三方库好像以前看到过关于它的中文的博客文章。
2019年01月14日 02点01分
level 9
太后知后觉了,果然是太监很久了....
不好意思,呵呵呵...
2017年12月02日 12点12分 21
level 1
帮楼主说一句,太监的应该不是楼主,是原作者。原作者没有继续写了,所以楼主也就无法转载了。
不管怎么样,非常感谢。
2019年01月05日 07点01分 22
level 1
好耶
2021年07月30日 11点07分 23
1