Prolog语言
Prolog,一种为人工智能(AI)和自然语言处理而生的语言。这一语言在法国诞生之时,就以逻辑编程为名:Pro代表编程,log代表逻辑。在上一个人工智能热潮中,Prolog语言成为当时的大热门(有点像现在的Python),比如:在日本以国家之力推进的“第五代计算机”工程,就将Prolog语言定为核心语言。后来,随着人工智能热的退潮,大家又回到了C++、Java之类的C系语言的怀抱。
到今天,虽然Prolog语言已颇为小众,但仍是一种有用而不失特点的语言。
一个Prolog程序可分为两部分:规则(Rule)和问题(Query)。
接下来,我们用两个例子来具体介绍Prolog程序的样子。
Hello World:苏格拉底会死吗?
第一个例子应当也必须足够简单。在这里,我们将求解一个简单的逻辑问题:苏格拉底会死吗?
首先,我们需要建立规则部分,包含两行内容:
- 知识:苏格拉底是人
human(socrates).
- 规则:人都会死
dies(X):- human(X).
在Prolog中,变量使用大写字母开头,常量则用小写字母开头(若无法用小写字母开头,也可以用单引号括起来)。可以看出,上面的X为变量,而socrates为常量。
接下来是逻辑判断问题:
- 苏格拉底会死吗?
启动Prolog,装入规则,并输入问题:
dies(socrates).
运行结果如下:

苏格拉底会死-运行结果(Prolog)
可以看出,Prolog根据已有知识进行了逻辑推理,得出了正确的结论:苏格拉底会死。
红楼梦人物关系
接下来,换一个复杂点了例子:红楼梦人物关系。
篇幅有限,我们把范围缩小到荣国府的贾家子女。先来一份关系图:

荣国府人物关系(Prolog)
然后,我们用其中的基本关系创建规则,其中每一行定义一条知识或规则。
先定义个人基本属性如:
贾政是男人:
man('贾政').
贾敏是女人:
woman('贾敏').
按这种方式定义其它人:
man('贾代善').man('贾政').man('贾赦').man('贾宝玉').man('贾环').man('贾琏').man('贾珠').man('林如海').woman('贾敏').woman('贾元春').woman('贾迎春').woman('贾探春').woman('林黛玉').woman('赵姨娘').woman('王夫人').
再定义亲子关系,比如:
贾政是贾代善的子女:
child('贾政', '贾代善').
以这种方式定义所有亲子关系:
child('贾政', '贾代善').child('贾赦', '贾代善').child('贾敏', '贾代善').child('贾元春','贾政').child('贾探春','贾政').child('贾宝玉','贾政').child('贾环', '贾政').child('贾珠', '贾政').child('贾元春','王夫人').child('贾珠', '王夫人').child('贾宝玉','王夫人').child('贾环', '赵姨娘').child('贾探春','赵姨娘').child('贾琏', '贾赦').child('贾迎春', '贾赦').child('林黛玉', '贾敏').child('林黛玉', '林如海').
接下来就是逻辑规则了:
- 父母的定义:若Y是X的子女,则X就是Y的父母
parent(X,Y):- child(Y,X).
- 兄弟姐妹的定义:(1) X是Z的子女,(2)Y是Z的子女,(3)X,Y又不是同一个人。当(1),(2),(3)同时成立时,结果成立,即X,Y为兄弟姐妹
sibling(X,Y):- child(X,Z), child(Y,Z), X\=Y.
- 祖先的定义之一:若X是Y的父母,则X是Y的祖先
ancestor(X,Y):- parent(X,Y).
- 祖先的定义之二:若Z是Y的祖先,而X是Z的父母,则X是Y的祖先。这是一条递归定义。
ancestor(X,Y):- parent(X,Z),ancestor(Z,Y).
最后,再来几行小工具:
children(X,Children):- findall(C, child(C,X),Children).siblings(X,Siblings):- findall(C, sibling(C,X),Siblings).parents(X,Parents):- findall(P, child(X,P),Parents).ancestors(X,Ancestors):- findall(A, ancestor(A,X), Ancestors).
这样,规则部分就完成了。
启动Prolog并载入规则即可解决问题。
试试看,贾政有哪些兄弟姐妹和子女?

贾政的兄弟姐妹 (Prolog)

贾政的子女(Prolog)
看来这子女数量不少啊。再看看贾宝玉有哪些兄弟姐妹?

贾宝玉的兄弟姐妹(Prolog)
我们再往知识库增加一点规则,表亲和堂亲,也就是叔伯婶舅的子女们:
定义:叔伯婶舅是父母的兄弟姐妹,而表亲堂亲则是叔伯婶舅的子女。(这里我们简化了很多,其实完全可以把叔叔、伯伯、舅舅、姨妈、姑姑这些亲戚全部分清楚):
uncle_aunt(X,Y):- parent(Z,Y), sibling(X,Z).cousin(X,Y):- uncle_aunt(Z,Y), child(X,Z).cousins(X,Cousins):- findall(C, cousin(C,X),Cousins).
再次启动Prolog,看看贾宝玉有哪些表亲堂亲呢?

贾宝玉的表亲和堂亲(Prolog)
结果出来了:表妹不多啊。林黛玉这个表妹,在当年算是亲上加亲,现在可就不行咯。
Prolog的安装和运行
如果使用PC/Mac/Linux系统,可以考虑安装SWI-Prolog。在Ubuntu Linux上一条命令就能装好:
sudo apt install swi-prolog
如果只是在Web上玩玩,可以考虑使用Tau-Prolog,直接访问 tau-prolog.org 就能在线使用了。
也可以用npm安装:
npm install tau-prolog
小结
我们简单介绍了Prolog语言,不知您有收获吗?如果您有有趣的推理问题,不妨试试用Prolog语言解题。
感谢阅读!
评论留言