1. ホーム
  2. haskell

論理型プログラミングと関数型プログラミングの違い

2023-08-16 21:46:42

疑問点

関数型プログラミングと論理型プログラミングの違いを理解しようと多くの記事を読んできましたが、今のところ論理型プログラミングは数式によってプログラムを定義するという推論しかできていません。しかし、そのようなことは論理プログラミングとは無縁です。

関数型プログラミングと論理型プログラミングの違いについて教えていただければと思います。

どのように解決するのですか?

論理型プログラミングは、数式でプログラムを定義するということではなく、関数型プログラミングのような感じですね。論理プログラミングは論理式を使っています(まあ、結局は論理は数学なんですけどね)。

私見ですが、関数型プログラミングと論理型プログラミングの大きな違いは、「構成要素」だと思います。述語は関数ではなく、戻り値を持ちません。引数の値によって真偽が決まりますが、いくつかの値が未定義の場合は、述語が真になるような値を探そうとします。

Prologは特に、以下のような特別な形式の論理節を使います。 ホーン節 と呼ばれる一階論理に属する特殊な論理節を用います。Hilogは高階論理の節を用います。

prolog述語を書くとき、あなたはホーン節を定義していることになります。 foo :- bar1, bar2, bar3. は、bar1、bar2、bar3が真であれば、fooは真であることを意味します。 if and only ifとは言っていないことに注意してください。1つの述語に対して複数の節を持つことができます。

foo:-
   bar1.
foo:-
  bar2.

は、bar1 が真、または bar2 が真のとき、foo が真であることを意味します。

論理型プログラミングは関数型プログラミングのスーパーセットであると言う人もいます。なぜなら、それぞれの関数は述語として表現できるからです。

foo(x,y) -> x+y.

は次のように書ける。

foo(X, Y, ReturnValue):-
   ReturnValue is X+Y.

というのがありますが、このような発言は少し誤解を招くと思います。

論理型と関数型のもう一つの違いは、バックトラックです。関数型プログラミングでは、一度関数本体に入ったら、失敗して次の定義に移ることはできません。たとえば、次のように書くことができます。

abs(x) -> 
   if x>0 x else -x

とか、ガードを使ってもいい。

abs(x) x>0 -> x;
abs(x) x=<0 -> -x.

とは書けません。

abs(x) ->
   x>0,
   x;
abs(x) ->
   -x.

一方、Prologでは、次のように書くことができます。

abs(X, R):-
   X>0,
   R is X.
abs(X, R):-
   R is -X.

を呼び出すと abs(-3, R) を呼び出すと、Prologは最初の節を試し、実行が -3 > 0 に達したときに失敗しますが、エラーは出ません。Prologは2番目の節を試して R = 3 .

関数型言語でも同様のものを実装することは不可能ではないと思います(ただし、私はそのような言語を使っていません)。

結局のところ、両パラダイムは宣言的であると考えられていますが、全く異なるものであり、両者を比較すると、関数型と命令型を比較しているように感じられるほどです。論理プログラミングを少しやってみるといいと思います。しかし、単にプログラムを書くだけでなく、その哲学を理解しようとするべきです。Prologでは、関数型や命令型のスタイル(とんでもない結果をもたらす)でさえ書くことができます。