算術計算
10.1 X=1+2の結果は...
Prologは記号計算が主で数値計算はあまり得意ではありません。Prologで算術計算を行う手段もかなり単純なものしかありません。詳しくは、使用するPrologの処理系によって異なってきますが、基本的なものは以下の通りです。
+ 加算
- 減算
* 乗算
/ 除算
mod 正数の剰余
加減乗除と剰余ですね。では、Prologに足し算をさせてみましょう。次のように質問したとします。
?- X = 1 + 2.
Prologは平然と
X = 1 + 2
と答えます。「そうじゃないってば!!」って言いたくなります。「1足す2は3でしょ。あんた、そんなこともできないの」って。
実は、このPrologの動作は正しいのです。=は右辺と左辺をユニファイさせます。つまり、X = 1 + 2 は、Xという変数が1 + 2とユニファイする、と規定しただけで実際の計算は何ら行っていないのです。
ここで、1 + 2 について少し考えてみましょう。加法も関数ですよね(大丈夫かな?)。1 + 2 で言えば、1と2という2つのパラメータに対して3という答えが得られるのですから、例えば、
plus(1,2)
と書いても良いですよね。いままでのPrologの関数の書き方では、こんなふうに関数子を先に書いていました。関数子を先に書く書き方を前置型の記述法と言います。でも、普段、私たちが目にする足し算の計算は
1 + 2
ですね。つまり、前置型に対して、中置型なわけです。中置型の記述法で見慣れてしまっているから、なんとなく関数ではない気がするかもしれませんが、加法も関数です(大丈夫よね)。だから、前置型で
+(1,2)
と書いても良いのです。この形になると計算式は構造だということがよくわかるでしょう。
話を戻します。X = 1 + 2 は、Xという変数が1 + 2とユニファイする、と規定しただけで実際の計算は何ら行っていないのです、と説明しました。このときのXは1 + 2という構造とユニファイしていたのです。変数が構造とユニファイするのは別に不自然なことではありませんでしたよね。
この=には注意してください。多くのプログラミング言語では、=は「左辺の計算結果を代入する」や「比較(等しいことを比較する)する」ことになっています。しかし、Prologでは、=は「右辺と左辺のユニファイ」ですから、具体的な計算や比較をしてくれはしません。実際、Prologでプログラムを組む場合、=はあまり使いません。「比較」ならば=:=ですし、「代入」ならば is です。
いまの足し算を正しく行わせるためには
?- X is 1 + 2.
としなければなりません。
参考までに
?- X is +(1,2).
の方も実行してみましょう。
10.2 算術計算
算術比較の記号には以下のものがあります。
X > Y XはYより大きい
X < Y XはYより小さい
X >= Y XはYより大きいか等しい
X =< Y XはYより小さいか等しい
X =:= Y XとYの値は等しい
X =\= Y XとYの値は等しくない
「以上」、「以下」の場合は不等号の閉じている方(尖っている方)にイコールを書きます。
もう一度、=について考えましょう。=と=:=の差、つまりX=YとX=:=Yとの違いについて考えます。例えば、次のようになることが判りますか。
?- 1 + 2 =:= 2 + 1.
yes
?- 1 + 2 = 2 + 1.
no
?- 1 + A = B + 2.
A=2
B=1
では、実際に算術計算を必要とするプログラムを作ってみましょう。前に「いろいろなプログラム」でも数の加算はやりました。ここでは、もう少し複雑なものを扱います。リストの要素の数を数えるlengthという関数を作ってみましょう。
lengthは次のように使います。
?- length([a,b,c,d,e],N).
N=5
?- length([a,[b,c,d],e],N).
N=3
lengthの考え方は以下の通りです。
- リストが空なら要素の数はゼロ
- リストListが空でないならList=[Head|Tail]であり、その要素の数はTailの要素の数に1加えたものに等しい
先ずは自力でプログラムを考えてみてください。プログラムが判ったら、あるいはお手上げになったら次へ進みましょう。
To be continue.....