Prolog 语言尝试

最近在看《七周七语言》这本书,其中有讲到 Prolog,感觉它跟平时自己用到的语言完全不同,是声明式的编程语言,因此安装尝试了一下。

什么是声明式编程语言?

我们之前常用的语言例如 JavaScript 等,被称为命令式语言(imperative language)。

命令式语言就像是一本烹饪菜谱,你需要精确告诉计算机如何去完成一项工作…你其实是在列出原料的购物清单,并描述烤蛋糕的详细步骤。

而 Prolog 是一门声明式编程语言(decalarative language)。我们提供事实和推论,Prolog 可以自己计算给出我们想要的推断。

声明式语言更像是一名手艺高超的糕点师,说出你喜欢的蛋糕的特征,让糕点师挑选原料并按照你提供的规则为你烤出蛋糕。

安装 Prolog

自从有了 WSL 以后,我更喜欢在 Windows 上进行编程了,我使用的是 Ubuntu 子系统,这里说一下如何在 Ubuntu 中安装 Prolog。

如果你还不了解 WSL,欢迎读一下我的另一篇博客: https://meixg.cn/2019/05/16/wsl/

Prolog 有很多实现,搜了一下有:B-Prolog, Ciao, ECLiPSe, GNU Prolog, Jekejeke Prolog, Poplog Prolog, P#, Quintus Prolog, SICStus, Strawberry, SWI-Prolog, Tau Prolog, tuProlog, WIN-PROLOG, XSB, YAP。。。

我选择的是 GNU-prolog,http://www.gprolog.org/,仅仅是因为书里是按照这个讲解的。

这里有个坑,Ubuntu 的 apt 中是直接可以搜索到 gprolog 这个包的,安装就可以直接运行。但是当你执行一些简单代码时,会发现有报错。

uncaught exception: error(existence_error(procedure,likes/0),friend/0) (Seven Languages)

搜索了一下,发现 apt 中的 Prolog 有 bug:https://stackoverflow.com/questions/54496409/uncaught-exception-errorexistence-errorprocedure-likes-0-friend-0-seven-la

解决办法是下载源码自己编译:

  1. 首先下载源码:

    1
    wget http://www.gprolog.org/gprolog-1.4.5.tar.gz
  2. 解压

  3. 进入 src 目录

    1
    2
    3
    ./congifure
    make
    sudo make install

就可以了,很简单。

Prolog 的基本构建单元

  • 事实。事实是关于真是世界的基本断言。
  • 规则。规则是关于真实世界中的一些事实的推论。
  • 查询。查询时关于真实世界的一个问题。

我们编写一些事实和规则,就可以进行查询,得到一些推论是不是正确,或者得到一些符合查询条件的结果。比如我们编写:

  • 事实:Babe 是一头猪。
  • 规则:如果一个动物是猪,那么它就喜欢泥巴。
  • 查询:Babe 喜欢泥巴吗?

编写简单 Prolog 代码

1
2
3
4
5
% 事实
isPig(babe).

% 规则
likeDirt(X) :- isPig(X).

那么我们就可以使用 likeDirt(babe) 来判断 babe 是不是喜欢泥巴了。

接下来看一个稍微难一点的问题,比如地图着色:

prolog-01.jpg

我们需要用红绿蓝三种颜色填充上面的地图,要求相邻州的颜色不同。

先写事实:

1
2
3
different(red, green). different(red, blue).
different(green, red). different(green, blue).
different(blue, red). different(blue, green).

编写规则:

1
2
3
4
5
coloring(A, M, G, T, F) :-
different(M, T). different(M, A),
different(A, M), different(A, G),
different(A, T), different(A, F),
different(G, F), different(G, T).

接下来我们执行一下试试。

使用 gprolog 执行 Prolog 代码

在安装好 gprolog 后,我们直接执行 prolog,会看到以下界面:

prolog-02.png

我们可以先加载我们的事实和规则文件:

1
['color.pl'].

prolog-03.png

返回 yes 表示加载成功了。之后进行查询:

1
coloring(A, M, G, T, F).

prolog-04.png

我们得到了一个填充方式,当然填充方式可能不止一种,输入 a 可以得到所有结果:

prolog-05.png

总结

Prolog 的这种编程方式,更像是我们在跟程序进行对话,计算过程我们并不知道,Prolog 根据我们输入的事实和规则,自己计算得到了查询结果。