Prologを使ってみる
(動作確認 程度のProlog入門)
%% これは、筆者が
技術評論社 刊 ソフトウェアデザイン誌
「つこてなんぼのFreeBSD」
1998年11月
SB-Prologを使う
に掲載した原稿をもとにしたものです %%
0. はじめに
この文書は、SWI Prolog, GNU Prolog, SB-Prologなどに適用できます。
GnuProlog, SWI-PrologはISO規格準拠のPrologです。
SB-Prologは、DEC10 Prolog準拠です。
1. Prologとは
Lispと同じくPorlogも人工知能用の言語として、1980年代には大いに利用さ
れました。
Prologは1980年代に産まれた新しい言語で、計算の原理が推論に基づいて
います。つまり、Prologのプログラムは一階述語論理の論理式で記述し、計算
の実行は、その論理式を論理推論することと同じです。
人間(ソクラテス). % ソクラテスは人間である
死ぬ者(X) :- 人間(X). % 人間であるような X ならば 死ぬ
を知識データベースに入れ、
?- 死ぬ者(ソクラテス).
という問い合わせを発行すると、ソクラテスは死ぬという結論が得られます。
ここでは、
ソクラテスは人間である。
人間なら死ぬ。
よって、ソクラテスは死ぬ。
という三段論法を一回実行していることになります。
そこで、Prologは知識情報処理のできる、高級言語であるといわれています。
実際には、Prolog処理系は、それを逆向きに推論します。よって、Prologを
プログラミング言語として見た場合に、実行をサブルーチンの呼び出しとして
見れば、
死ぬ者 -> 人間
という順序で、通常のプログラミング言語と違和感なく使用できます。
Prologは、通産省の、第5世代コンピュータ(知識処理を行うとされた)開発計
画の中核言語にもなり、日本は世界でも有数のProlog使用国です。
Prologは、研究用に作られた処理系がたくさん有り、産まれが新しいので、
フリーに配られているものも多くありました。
% しかし、最近ではどのProlog処理系も開発が止まっており、 Intel系のUNIX
ですぐに動く処理系はほとんどありません。%
2. WAMとSB Prolog
1)WAM
Prologを効率よく実行するためには、
こういうアーキテクチャのコンピュータがあればよい、という、モデルとして、
「WAM:
Warrenの抽象機械(Warren's Abstract Machine=WAM)」
というものがあります。
WAMはDavid Warrenという人が考案したものです。
WAMは、そもそも、WarrenがPrologのコンパイリングの研究のために考えたものです。
しかし、WAMは Prolog実行の本質をついていたので、WAM以降、
Prologマシンのアーキテクチャは強くWAMの影響を受けます。
日本で第5世代計算機を研究していたICOTのPrologマシンも、WAM以降はWAMを
モディファイしたものになっていきます。
2) SB-Prolog
David WarrenはSB-Prologの作者の一人です。
SB-PrologはStony BrookにあるSUNYのDavid WarrenとSuzanne Dietrichによっ
て作られ、メンテナンスがアリゾナ大学に移って、現在に至ります。とはいえ、
1987年以来まったく変化がありません。
SB-PrologはそのWarrenが作った処理系なので興味深いものがあります。
SB-Prologには、コンパイラもありますが、そのオブジェクトは、WAMをター
ゲットとしたものになっています。
そして、SB-Prologの実行系は、実は、WAMのインタープリタです。
つまり、CでWAMの仮想マシン・インタープリタを記述し、実行はWAMインター
プリタが行います。
また、SB-Prologでは、そのほとんどの機能がPrologで記述してあります。
SB-Prologでは、Prologのコンパイルがネイティブな機械語でなく、WAMへの
コンパイルなので、実行速度に不満はあります。とはいえ、前回のGCL(KCl)と
同様、ネイティブ・コードへのコンパイリングでないおかげで、この時代でも
簡単に使用できるのです。
普通のスペックのPrologが、手軽に使えるのですから、多少のオーバヘッド
は我慢するしかないでしょう。
なお、SB-PrologはPrologの標準的な文法であるDEC10 Prologに準拠していま
す。
有名なC-PrologやQuintus-Prologともほぼコンパチブルです。
3. Prologの動作確認/簡単な使い方
普通のProlog処理系は、対話的に動作するようになっています。
したがって、起動すると、処理系は、プロンプトを表示して、
入力待ちになります。
起動直後に
| ?- (SB Prolog)
1 ?- (SWI Prolog)
という風なプロンプトが表示されれば正常です。
(プロンプトは処理系ごとに異なります)
※以下の実行例は、SB-Prologのものですが、他のPrologでも、ほぼ同様です。
Prologのプロンプトでは、節を入力しなければなりません。
Prologのプログラムは節の集まりです。
節の定義は対話的にも可能です。しかし、それは、
節を定義するための、節を入力することです。
それは非常に繁雑なので、プログラム・ファイル
をロード(consult)するのが簡単です。
エディタで次の様なファイル
append.prolog
を作成します。
--- append.prolog
%% Append
append([],X,X).
append([A|X],Y,[A|Z]):- append(X,Y,Z).
--- ここまで
では、Prologにロードしましょう。
| ?- consult('append.prolog').
yes
| ?-
となります。
さて、appendを実行します。
| ?- append([a,b,c], [x,y,z], X).
X = [a,b,c,x,y,z] ここで一旦停止するので、「return」を入力
yes
| ?-
と、2つのリスト[a,b,c]と[x,y,z]がつながれています。
通常のプログラミング言語ならこれでおしまいですが、Prologの高級さは、こ
れだけではありません。
| ?- append(X,Y,[a,b,c,d]).
X = []
Y = [a,b,c,d]; ここで一旦停止するので、「;」「return」を入力
X = [a]
Y = [b,c,d];
X = [a,b]
Y = [c,d];
X = [a,b,c]
Y = [d];
X = [a,b,c,d]
Y = [];
no
| ?-
このように、答を入れると問題が出るという、はなれ技。
Prologの実行はあくまで論理式の正しさに依っているので、双方向の実行が可
能なのです。
途中の入力は、「;」を入力すると、ORを意味し、別な解を求めに行きます。もうそれ以上の解答が必要ない場合は、単に「return」を入力して探索を打ち切ります。
DEC10 prolog系では、変数は大文字で記述し、定数は小文字で記述します。
また、
append([A|X],Y,[A|Z]):- append(X,Y,Z).
で使用している、[A|X]は、リストのcarとcdrを分解してパターンマッチさせる
記述で、この場合、変数Aにリストのcarが変数Xにcdrがマッチしてバインドされ
ます。
さて、ソクラテスの例もできます。
socrates.prolog
(SB-Prologは漢字は使えないので英語です)
--- socrates.prolog
human(socrates).
mortal(X) :- human(X).
---ここまで
実行は
| ?- consult('socrates.prolog').
yes
| ?- mortal(socrates).
yes
ということで、ソクラテスは死ぬことが判ります。:-)
また、算術演算もできます。
fact.prolog
--- fact.prolog
%% fact
fa(0,1) .
fa(N,X) :- N1 is N -1 , fa(N1,X1),X is X1 * N .
---ここまで
実行は
| ?- consult('fact.prolog').
yes
| ?- fact(6,X).
X = 720
yes
ということで、階乗も計算できます。
isは単一方向の代入であり、
N1 is N-1
は、 Cで書く
N1=N-1;
と同じ意味です。
また、算術四則演算子は中置き記述が可能です。
たけおかのPrologページ 目次
Prologの入門文書に飽きた人に
GnuEmacsと、Prologを一緒に使うと便利! こちら。
実際にProlog処理系を使ったときの、あれこれ
Prologで記述した、StarTrek(1976年頃流行した古いゲーム)
たけおか(竹岡尚三)のホームページ
--- EOF