知る人ぞ知る Prolog と数学の本。
数学者が Prolog と出会った時の驚きと喜びを感じることができる。 レーザプリンタで出した原稿をそのまま版下としたところにも、その感情がわかる。 私は S-Prolog という、当時 (1990 年前後)利用できた処理系を使って少しずつ検証したのだけれど、 あるところまでいったら検証がうまくいかなくなって挫折した。 久しぶりにいじってみようかと思ったのだが、 今はどんな処理系があるのかわからない。
後記:今は GNU Prolog と SWI-Prolog を使ってみて、 SWI-Prolog のほうが良さそうなので、こちらでこの本の検証をしている (2008-04-08)。
後記:最近 RUN/PROLOG を懐かしんで作成された N-Prolog が利用できることがわかったので、こちらでもこの本を検証している(2022-12-24)。
本書では、run/prolog というパソコンの処理系を使って検証している。 この処理系は、現在(2022年)は利用不可と思われる。 そこで本書の内容を、現在も利用可能な次の 3 種類の処理系で検証した。
結論を先に言えば、N-Prolog と swi-prolog ではほとんどが実行できたが、 gprolog では問題が多くあり、いくつか実行できなかった。
p.13 で説明されている、アリティを指定した述語を取り出すことが N-Prolog ではできない。
?- system(P/0). no
p.30 で本書では integer(123456) は no を返すが、N-Prolog では yes を返す。時代を感じる。
p.44 で、
?- edit(sum).の入力で sum.ari という名前をもつファイルの編集に入るが、N-Prolog では拡張子はつかず、 sum という名前のファイルの編集となる。ファイルの拡張子をつけて編集するには、
?- edit('sum.pro').のようにシングルクォーテーションが必要だ。
p.68 では一般互除法のアルゴリズムの説明がある。このアルゴリズムのプログラム
gcd(A=A*1+B*0).
gcd(D=A*X+B*Y):-
res_q(A=B*Q+R),
(A1,B1)=(B, R),
gcd(D=A1*X1+B1*Y1),
T is X1-Y1*Q, (X,Y) = (Y1,T).
を読み込ませると、N-Prolog では次のようにエラーが出る。line=11 は gcd(A=A*1+0*0). がある行だ。
?- consult('math-n.pro').
Syntax error assertz gcd(A=A*1+B*0)
around here line=11 column=15
p.88 では append/1 を定義するプログラム 5.4 があるが、次のエラーが出る。
Permission error assertz append(Z=[]+Z) around here line=40 column=19
これは、すでに組み込み述語(拡張) append/3 があるためだ(system(P) で表示されるのは append/2 だがこれは誤り)。 アリティが違うが名前 append が衝突するためである。本書の append/1 を たとえば myappend/1 のように変更すれば問題ない。 なお、swi-prolog では append/1 のままの定義で正常に動作する。
13ページ、述語 system/1 は使えない。gprolog, swi-prolog ともに、current_predicate/1 である。
24-25ページ、前の式の修正方法は、 gprolog, swi-prolog とも、emacs 風キーバインドである。
29-30ページ、関数 integer/1 は四捨五入である。
§ 2.1 パターン・マッチ での
?- A*B=2+3.
で表示されるのは、no ではなく false である。
?- Z+Y=X+3.
で表示されるのは、
Z = X,
Y = 3
である。
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になる。
なお、integer は、引数が整数か否かを判定する述語としての機能はある。
31ページ、 pi/0 という定数関数はない。
/** 問1 0 から I までの 2 乗の和を求める述語 sqr_sum/2 **/
sqr_sum(0, 0).
sqr_sum(J, S1) :- I is J-1, sqr_sum(I, S), S1 is S + J * J.
/** 問2 0 から I までの N 乗の和を求める述語 power_sum/3 **/
power_sum(0, 0, N).
power_sum(J, S1, N) :- I is J-1, power_sum(I, S, N), S1 is S + J ^ N.
/** 問1 1 から N までの 逆数の和を求めるプログラム **/
inv_sum(1, 1.0).
inv_sum(J, S1) :- I is J-1, inv_sum(I, S), S1 is S + 1.0 / J.
/** 問2 省略 **/
問1 では、(S が4 を超えるのはNがいくつになればよいか. )という問もある。 これについては、次の結果から N が 31 になればいい」というのが答である。
?- inv_sum(30, S). S = 3.994987130920391 . yes ?- inv_sum(31, S). S = 4.02724519543652
p.68 では一般互除法のアルゴリズムの説明がある。このアルゴリズムは、本書では次のプログラムで表される。
gcd(A=A*1+0*0).
gcd(D=A*X+B*Y):-
res_q(A=B*Q+R),
(A1,B1)=(B, R),
gcd(D=A1*X1+B1*Y1),
T is X1-Y1*Q, (X,Y) = (Y1,T).
最初の行は、正しくは次のとおりである。
gcd(A=A*1+B*0).
書名 | Prolog で作る数学の世界 |
著者 | 飯高茂 |
発行日 | 1990 年 6 月 20 日(初版第1刷) |
発行元 | 朝倉書店 |
定価 | 2300 円(本体) |
サイズ | A5 版 |
ISBN | 4-254-11054-5 |
備考 | 現在手元にはない |
まりんきょ学問所 > 関数型言語 > Prolog > 飯高茂:Prolog で作る数学の世界