プログラムを動かしてみる



Prologは記号処理向けのプログラミング言語です。もっと具体的な言い方をすると、何らかの「もの(対象)」と「もの(対象)」との関係に関する問題解決に適しています。この章では例題を通してPrologの基本的なメカニズムについて考えてみます。何はともあれ、Prologを動かしてみましょう。

1.1磯野家の家族関係

先ず、人と人の関係を考えてみましょう。「波平がサザエの親である」という関係をPrologでは以下のように表現することができます。
          parent(namihei,sazae).
ここでは、parentが関係の名称であり、namiheiとsazaeはその引数となっています。namiheiとsazaeは、小文字で書かなければなりません。後述しますが、大文字で始める名称は「変数名」になるからです。それでは、磯野家の家族関係の一部をPrologで定義してみましょう。
          parent(namihei,sazae).
          parent(namihei,katuo).
          parent(namihei,wakame).
          parent(fune,sazae).
          parent(fune,katuo).
          parent(sazae,tara).
このプログラムの1行をと言います。文頭またはピリオドの次の文字からピリオドまでが節です。各節はparent関係について「ある人物がある人物の親である」という1つの事実を定義しています。

このプログラムをPrologに与えると、Prologはparent関係についての質問に答えることができるようになります。上の6行分のプログラムをエディタで入力し、Prologに読み込んでみましょう。質問はPrologインタプリタのプロンプトから以下のように行います。
          ?- parent(sazae,tara).
この質問は、「サザエはタラの親か」という意味です。Prologは読み込んだプログラムの中に同一の節を発見し、次のように答えます。
          yes
また、
          ?- parent(fune,wakame).
という質問に対して、prologは
          no
と答えます。実際にワカメちゃんが舟さんの娘かどうかというよりも、プログラムの中にそのような記述がないことから、Prologはnoと答えるのです。だから、
          ?- parent(masuo,tara).
という質問に対しても、Prologはnoと答えます。noというのは「違う」というよりも「知らない」という意味に近いのです。Prologはそのような知識を持っていません、というのがnoなのです。

Prologはyes/noを答えるだけではありません。
          ?- parent(X,tara).
という質問は、「タラちゃんの親は誰か」という意味です。この質問に対してPrologは
          X = sazae
と答えます。いま、Prologはマスオさんのことを知りませんから、タラちゃんの親はサザエさんだけですね。では、カツオの場合はどうでしょう。
          ?- parent(X,katuo).
「カツオの親は誰か」という問に対して、波平と舟という複数の解答が可能です。このような場合、Prologは先ず1つの解を答えます。
          X = namihei
これは、parent(namihei,katuo).という記述がparent(fune,katuo).よりに書かれているからです。他の解を求めるためには、セミコロンを入力します。この場合のセミコロンは「その解ではなくて、もっと別の解が欲しい」の意味になります。ですから、ここでセミコロンを入力すると、Prologは
          X = fune
と答えます。もし、更にセミコロンを入力して別解を求めようとすると、解は出尽くしているのでPrologはnoと答えます。

勿論、親だけではなくて子供について質問することもできます。「波平の子供は誰か」という質問は
          ?- parent(namihei,X).
となりますし、更に「誰が誰の親/子か」という質問は
          ?- parent(X,Y).
となります。この質問に対して、Prologは親と子の全ての対をプログラムに記述されている順に答えていきます。
          X=namihei
          Y=sazae;

          X=namihei
          Y=katuo;

          X=namihei
          Y=wakame;

          ......
セミコロンの代わりにピリオドを入力すると、別解の出力を止めることができます。

1.2タラちゃんのおじいちゃんは波平さん

それでは、「タラちゃんの祖父は誰か」について考えてみましょう。 いま、私たちが使っている6行のプログラムには親子関係は定義されていますが、祖父母の関係については何の記述もありません。ですから、このままではPrologはタラちゃんの祖父について答えることができません。でも、親子関係については判っているわけですから、「タラちゃんの祖父は誰か」という質問を次のように2段階に分けて考えましょう。 このような質問は、2つの質問をカンマで連結して列とすることによって、次のように行います。
          ?- parent(Y,tara),parent(X,Y).
答えは次のようになります。
          X=namihei
          Y=sazae
この質問(合成質問)は、parent(Y,tara)とparent(X,Y)とを満たすXとYとを見つけよ、と読めます。ですから、この場合は質問の順番を変えても同じで、
          ?- parent(X,Y),parent(Y,tara).
でも同じ答えになります。

更に、「サザエとカツオの親は同じか」という質問も可能です。これも2段階に分けて考えます。 この質問をPrologに行うと、
          ?- parent(X,sazae),parent(X,katuo).
です。その答えは
          X=namihei
となります。

ここでいくつか言葉の定義とPrologの基本的なメカニズムの復習をしておきましょう。Prologへの質問は1つまたは複数個の目標(goal)と見なされます。つまり、
          ?- parent(X,sazae),parent(X,katuo).
の場合、parent(X,sazae).という目標とparent(X,katuo).という目標があるわけです。Prologが解を発見したとき、目標が充足されたまたは成功したと言います。また、解を発見できなかったとき、つまりnoと答えた場合、目標が充足されなかったまたは失敗したと言います。

人間からみると、いままでPrologインタプリタのプロンプトから入力したものは「質問」ですが、Prologにしてみれば、これらは「満たすべき目標」なわけです。Prologはどうしたら目標を充足することができるか、いろいろ試みます。全く同じ内容の節がプログラム中に存在すれば、目標は充足されます。したがって、Prologはyesと答えます。また、目標の中の変数に何らかの値を設定することによって目標を充足することができるのであれば、Prologはその変数の値を答え、目標は充足されたものとします。しかし、同じ内容の節がプログラム中には存在せず、また、目標の中の変数に何らかの値を設定してもプログラム中の節と同じ内容にはならない場合は、目標は充足されません。したがって、Prologはnoと答えることとなります。





《演習問題》

次の質問をPrologに対して行いなさい。
目次に戻る目次に戻る