逻辑语言Prolog介绍(1):苏格拉底与荣国府

人工智能
后台-插件-广告管理-内容页头部广告(手机)

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介绍(1):苏格拉底与荣国府

苏格拉底会死-运行结果(Prolog)

可以看出,Prolog根据已有知识进行了逻辑推理,得出了正确的结论:苏格拉底会死。

红楼梦人物关系

接下来,换一个复杂点了例子:红楼梦人物关系。

篇幅有限,我们把范围缩小到荣国府的贾家子女。先来一份关系图:

逻辑语言Prolog介绍(1):苏格拉底与荣国府

荣国府人物关系(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介绍(1):苏格拉底与荣国府

贾政的兄弟姐妹 (Prolog)

逻辑语言Prolog介绍(1):苏格拉底与荣国府

贾政的子女(Prolog)

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

逻辑语言Prolog介绍(1):苏格拉底与荣国府

贾宝玉的兄弟姐妹(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介绍(1):苏格拉底与荣国府

贾宝玉的表亲和堂亲(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语言解题。

感谢阅读!

后台-插件-广告管理-内容页尾部广告(手机)
标签:

评论留言

我要留言

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。