論理型言語 Prolog

作成日: 2008-03-16
最終更新日:

Prolog とは

論理型言語として、かなり昔にもてはやされた。 現在は昔ほどは流行していないが、そのパターンマッチ (ユニフィケーション)機能は魅力的だ。

また、Prolog に並列処理機能を付加した処理系から出発して、 独自の進化を遂げた言語に Erlang がある。 現在はこちらの人気が高い。

Prolog のインストール

2種類の処理系を使ってみた。 GNU prolog (コマンド名は gprolog )と swi-prolog (コマンド名は pl) である。 gprolog は、Vine Linux のパッケージで apt-install できる唯一の処理系である(Vine 4.1 から Vine 5.1 まで)。 一方、swi-prolog は、無料で取得できる処理系の中で最もよく知られている。

swi-prolog のインストール(Vine 4.1)の場合

世の中では、gprolog より、swi-prolog のほうが、評判が高い。 まず、swi-prolog のダウンロードサイトにある rpm パッケージを入れてみようとしたが、 下記のメッセージが出てエラーとなった。

$ rpm -ivh ~/rpm/pl-5.6.52-310.i586.rpm
エラー: 依存性の欠如:
				/usr/bin/../pl.sh は pl-5.6.52-310.i586 に必要とされています
				libexpat.so.1 は pl-5.6.52-310.i586 に必要とされています
				libpthread.so.0(GLIBC_2.3.3) は pl-5.6.52-310.i586 に必要とされています

従って、ソースをコンパイルした。 特に問題なく、次の手順で使える。

$ ./configure
$ make
$ sudo make install

swi-prolog のインストール(Vine 5.1)の場合

久しぶりに Vine Linux を使うことにした。バージョンは 5.1 である。 また、swi-prolog のバージョンは 5.8.3-376であった。

$ rpm -ivh pl-5.8.3-376.i586.rpm 
エラー: 依存性の欠如:
	rpmlib(PayloadIsLzma) <= 4.4.2-1 は pl-5.8.3-376.i586 に必要とされています

この原因を追求するのもよいが、ダウンロード先では「バイナリーは移植性に乏しいのでソースからコンパイルするように」 と書かれていた。そこで、ソースコードからコンパイルした。

% tar zxvf pl-5.8.3.tar.gz
% cd pl-5.8.3/src
% ./configure
% make
% su
# make install

途中でウォーニングは出たが、取りあえずコンパイルは完了した。 うまく動くだろうか。

$ pl
Welcome to SWI-Prolog (Multi-threaded, 32 bits, Version 5.8.3)
Copyright (c) 1990-2009 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

?- halt.
$

無事起動し、無事終了した。

swi-prolog のインストール(Vine 6.3)の場合

2016 年 2 月 14 日である。久しぶりに Vine Linux を使うことにした。バージョンは 6.3 である。

git をインストールするのがよいと swi-prolog のページにあったので、 まずは git をインストールした。

$ sudo apt-get install git

さて、swi-prolog のインストールだ。

参考 http://www.swi-prolog.org/git.html

$ git clone https://github.com/SWI-Prolog/swipl
$ cd swipl
$ ./prepare
(中略)
Do you want me to run git submodule update --init? yes
(中略)
All submodules are up-to-date

Could not find documentation. What do you want to do?

1) Download and unpack documentation from http://www.swi-prolog.org
and do this again automatically next time
2) Download and unpack documentation from http://www.swi-prolog.org
and ask next time
3) Warn only

Option? 1
(中略)
$ cp -p build.templ build
$ ./build
All submodules are up-to-date
Generating configure in ./src ... configure.in:4: error: Autoconf version 2.66 or higher is required
configure.in:4: the top level
autom4te: /usr/bin/m4 failed with exit status: 63
autoheader: '/usr/bin/autom4te' failed with exit status: 63
configure.in:4: error: Autoconf version 2.66 or higher is required
configure.in:4: the top level
autom4te: /usr/bin/m4 failed with exit status: 63
done
Your kit is prepared.
Please consult INSTALL for further instructions.
./configure: 行 77: ../src/configure: そのようなファイルやディレクトリはありません

さあどうしよう。上で、

Generating configure in ./src ... configure.in:4: error: Autoconf version 2.66 or higher is required

と出ているところが問題なのだろう。調べた。

$ autoconf --version
autoconf (GNU Autoconf) 2.65
Copyright (C) 2009 Free Software Foundation, Inc.

ガーン!バージョンがコンマ01足りない。

今度は最新版の autoconf を入れることにした。まったく Vine Linux はバージョンが古いなあ。

$ cd ../autoconf-2.69
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
(中略)
checking for GNU M4 that supports accurate traces... configure: error: no acceptable m4 could be found in $PATH.
GNU M4 1.4.6 or later is required; 1.4.16 or newer is recommended.
GNU M4 1.4.15 uses a buggy replacement strstr on some systems.
Glibc 2.9 - 2.12 and GNU M4 1.4.11 - 1.4.15 have another strstr bug.
$

おかしいな。m4 は普通入っているはずだが。

$ m4 --version
m4 (GNU M4) 1.4.14
Copyright (C) 2010 Free Software Foundation, Inc.
(後略)
$

これもバージョンが古いのか。困ったな。m4 も最新バージョンを入れるか。

$ cd ../m4-1.4.17
$ ./configure
$ make
$ sudo make install
$ m4 --version
m4 (GNU M4) 1.4.17
Copyright (C) 2013 Free Software Foundation, Inc.
(後略)
$

まずはほっとする。次は autoconf だ。

$ ./configure
$ make
$ sudo make install
$ autoconf --version
autoconf (GNU Autoconf) 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
$

autoconf まではうまくいったようだ。もとに戻ろう。

$ ./build
All submodules are up-to-date
(中略)
pl-gmp.c: In function ‘cmpFloatNumbers’:
pl-gmp.c:983: error: ‘V_MPZ’ undeclared (first use in this function)
pl-gmp.c:983: error: (Each undeclared identifier is reported only once
pl-gmp.c:983: error: for each function it appears in.)
(中略)
make: *** [lite] エラー 2
$

どうやら、gmp (GNU の多倍長パッケージ)の読み込みの問題らしい。

$ sudo apt-get install gmp-devel
$ make clean
$ ./configure
$ make
$ sudo make install
$

これで懸案の問題は解決した。

Prolog で作る数学の世界

飯高茂による「Prolog で作る数学の世界」という本がある。この本の内容を、 上述の2種の処理系で突き合わせて検証した。 結論を先に言えば、swi-prolog ではほとんどが実行できたが、 gprolog では以下の問題があり、いくつか実行できなかった。 この結果からも、gprolog より swi-prolog が優れていることがわかる。 なお、上述の本では、run/prolog というパソコンの処理系を使って検証している。 この処理系は、今でも利用可能かどうかはわからない。

以下は、gprolog の場合。特記なき限り、swi-prolog では問題がない。

4ページ、ベキ乗計算に ^ は使えない。** を使う。

7ページ、述語 concat は使えない。

13ページ、述語 system/1 は使えない。これは、swi-prolog でも同様に使えない。 gprolog, swi-prolog とも、current_predicate/1 である。

24-25ページ、前の式の修正方法は、 gprolog, swi-prolog とも、emacs 風キーバインドである。

29-30ページ、関数 integer は、切り捨て機能を持たない。 切り捨て機能をもつのは floor である。 これは、実数 r の整数部分の定義である。 r 以下の最大整数の意味に沿っている。 すなわち、floor(-5.6)は、正しく-6になる。

一方、swi-prolog は integer/1 は四捨五入である。

なお、integer は、引数が整数か否かを判定する述語としての機能はある。

31ページ、 pi/0 という定数関数はない。(gprolog)

swi-prolog との比較

第2章のパターン・マッチから、swi-prolog との比較のみに焦点を絞る。

2.1 パターン・マッチ

?- A*B=2+3.

で表示されるのは、no ではなく false である。

?- Z+Y=X+3.

で表示されるのは、
Z = X,
Y = 3

である。

まりんきょ学問所関数型言語手習い > 論理型言語 Prolog


MARUYAMA Satosi