Learn Prolog Now!
http://www.learnprolognow.org/lpnpage.php?pageid=online
の1.1節を翻訳しました.
翻訳の誤りなどあればご指摘お待ちしております
1.1 いくつかの簡単な例
Prologには基本的な構成概念がたった3つ存在します、事実、ルール、およびクエリです。事実とルールの集合は、知識ベース(またはデータベース)と呼ばれ、Prologのプログラミングは、要は知識ベースを書くことです。つまり、Prologプログラムは単なる知識ベース、すなわち私たちが関心を持ついくつかの関係を記述する、事実とルールの集合です。
どうやってPrologのプログラムを使用するのでしょうか?クエリ、つまり、知識ベースに格納されている情報に関する質問をすることによってです。
現段階では、これはおそらく、やや奇妙に聞こえるでしょう。確かに、プログラミングですべきことについて、まったく明らかではありません。コンピュータに何をすべきか伝えることについて、結局のところすべてプログラミングしていませんか?しかし、これから見るように、Prologのプログラミングの方法は、少なくとも特定のタスクにとっては、多くの意味を持ちます。例えば、それは計算言語学と人工知能(AI)に有用です。Prologについてより詳細な説明をする代わりに、すぐに始め、いくつかの簡単な知識ベースを書いてみましょう。これはPrologを学習する最善の方法ではなく、唯一の方法です。
知識ベース1
知識ベース1(KB1)は、単純な事実の集まりです。事実は、関心のあるなんらかの状況において、無条件に真であることについて述べるために用いられます。例えば、ミア、ジョディ、そしてヨランダが女性であること、ジョディはエアギターを演奏すること、パーティーが行われていることを、次の5つの事実を使用して述べることができます。
woman(mia).
woman(jody).
woman(yolanda).
playsAirGuitar(jody).
party.
この事実の集合がKB1です。これは、私たちのPrologプログラムの最初の例です。名前の「mia」、「jody」、「yoland」、属性の「woman」、「playsAirGuitar」、命題の「party」の最初の文字が小文字であることに注意してください。これは重要です。後で理由を説明します。
KB1をどのように使うことができるのでしょうか?クエリ、つまりKB1に含まれる情報に関する質問をすることによってです。ここではいくつかの例を示します。クエリにより、ミアが女性かどうか、Prologに尋ねることができます。
?- woman(mia).
Prologは以下のように答えるでしょう。
yes
なぜなら、KB1に明示的に記録された事実の一つであるという明白な理由があるからです。なお、「?-」は入力しません。この記号(または、使用しているPrologの実装によっては、似たような何か)は、Prologインタプリタがクエリの評価を待機しているときに表示される、プロンプト記号です。私たちは(例えば「woman(mia)」のような)実際のクエリと、続く「.」(終止符)を入力します 。ピリオドは重要です。それを入力しないかぎり、Prologは、クエリの作業を開始しません。
同様に、以下の問合せをすることにより、ジョディがエアギターを演奏するかどうかを尋ねることができます。
?- playsAirGuitar(jody).
これはKB1の事実の1つであるため、Prologは再び、「yes」と答えます。しかし、ミアがエアギターを演奏するかどうかを尋ねたとします。
?- playsAirGuitar(mia).
以下の答えを得るでしょう。
no
なぜでしょうか?さて、まず第一に、これはKB1の事実ではありません。さらに、KB1はとても単純で、ミアがエアギターを演奏するかどうかについて、Prologが推測(すなわち、演繹(deduce))するのに役立つかもしれない他の情報(例えば、簡単に説明した、ルールなど)が含まれていません。そのため、Prologは「playsAirGuitar(mia)」はKB1から導かれないと正しく結論づけます。
2つの重要な例を示します。まず、以下の質問をするとしましょう。
?- playsAirGuitar(vincent).
再びPrologは「no」と答えます。なぜでしょうか?このクエリは、KB1には情報がない人(ヴィンセント)に関するものなので、「playsAirGuitar(vincent)」がKB1の情報から演繹することができないと(正しく)結論づけます。
同様に、以下の質問をしたとします。
?- tatooed(jody).
再びPrologは「no」と答えます。なぜでしょうか?このクエリは、KB1には情報がない属性(タトゥーがあるか?)に関するものなので、再び、クエリがKB1の情報から演繹することができないと(正しく)結論づけられます。 (実際には、いくつかのPrologの実装では、「tatooed」という述語または手続きが定義されていないことを伝えるエラーメッセージを表示して、このクエリに応答します。述語の概念はすぐに紹介します。)
言うまでもなく、命題に関する問合せをもすることができます。例えば、以下の質問をしたとしましょう。
?- party.
Prologは
yes
と答えます。
次の質問の場合、
?- rockConcert.
Prologは
no
と答えます。
知識ベース2
第二の知識ベースKB2は、次のとおりです。
happy(yolanda).
listens2Music(mia).
listens2Music(yolanda):- happy(yolanda).
playsAirGuitar(mia):- listens2Music(mia).
playsAirGuitar(yolanda):- listens2Music(yolanda).
KB2には、「listens2Music(mia)」と「happy(yolanda)」という2つの事実があります。それらが含まれている残りの3項目が、ルールです。
ルールは、対象の状況における条件付き真実の情報を述べます。例えば最初のルールは、ヨランダが幸せであれば彼女は音楽を聞き、最後のルールは、ヨランダが音楽を聞く場合彼女はエアギターを演奏することを述べています。より一般的に、「:-」は「もしも」、または「~によって暗示されている」と解釈できます。「:-」の左側の部分をルールの頭部(head)、右側の部分をルールの体部(body)と呼びます。一般的に、ルールは次のことを述べます、「もしもルールの体部がtrueならば、ルールの頭部もまた真である」。重要なポイントを示します、
知識ベースがルール「head :- body」を含み、Prologが知識ベースの情報から「body」が導かれると知っている場合、Prologは「head」を推測することができます。
この基本的な演繹ステップは前件肯定(modus ponens)と呼ばれています。
例を考えてみましょう。ミアがエアギターを演奏するかどうかを尋ねたとします。
?- playsAirGuitar(mia).
Prologは「yes」と応答します。どうしてでしょうか?まず、「playsAirGuitar(mia)」は明示的にKB2に記録された事実としては見つけることができませんが、以下のルールは見つけることができます。
playsAirGuitar(mia):- listens2Music(mia).
さらにまた、KB2は事実「listens2Music(mia)」も含んでいます。したがって、Prologは前件肯定の規則を使用することができ、「playsAirGuitar(mia)」と演繹することができます。
次の例では、Prologが前件肯定をつなげて使用できることを示します。以下の質問を仮定します。
?- playsAirGuitar(yolanda).
Prologは「yes」と答えます。どうしてでしょうか?まず第一に、事実「happy(yolanda)」とルール
listens2Music(yolanda):- happy(yolanda).
を用いて、Prologは新しい事実「listens2Music(yolanda)」を演繹することができます。この新しい事実は知識ベースに明示的には記録されていません、暗黙的に存在するだけです(これは推測された知識です)。それにもかかわらず、Prologは、明示的に記録された事実とまったく同様にそれを使用することができます。具体的には、この推論された事実と以下のルール
playsAirGuitar(yolanda):- listens2Music(yolanda).
から、私たちの問合せそのものである「playsAirGuitar(yolanda)」を演繹することができます。要約すると、前件肯定を適用することによって生成される任意の事実は、さらにルールへの入力として使用することができます。このように前件肯定の適用を連鎖することにより、Prologは知識ベースに記録されたルールと事実から論理的に導かれる情報を引きだすことができます。
知識ベースに含まれている事実やルールは節(clause)と呼ばれています。つまり、KB2は、5つの節、すなわち3つのルールと2つの事実を含みます。 KB2のもう一つの見方は、3つの述語(または手続き)で構成されているというものです。 3つの述語は、以下のとおりです。
listens2Music
happy
playsAirGuitar
「happy」述語は、単一の節(事実)を使用して定義されます。 「listens2Music」と「playsAirGuitar」述語は、それぞれ2つの節(一方は2つのルール、他方は1つのルールと1つの事実)を使用して定義されます。Prologプログラムについて、含まれている述語の観点から考えることは良いアイデアです。本質的には、述語は、(私たちが見つけ出した重要な)概念であり、(私たちがそれらについて書き留めた)さまざまな節は、それら(述語)が何を意味し、相互にどのように関連しているかを釘づけにするための試みです。
最後にひとつ注意。事実は、体部が空のルールとみなすことができます。つまり事実は、いかなる先行条件も持たない条件文、または縮退したルールとしてとらえることができます。
知識ベース3
KB3、第三の知識ベースは、5つの節で構成されています。
happy(vincent).
listens2Music(butch).
playsAirGuitar(vincent):-
listens2Music(vincent),
happy(vincent).
playsAirGuitar(butch):-
happy(butch).
playsAirGuitar(butch):-
listens2Music(butch).
2つの事実「happy(vincent)」と「listens2Music(butch)」と、3つのルールがあります。
KB3はKB2と同じ3つの述語(すなわち、「happy」、「listens2Music」、「playsAirGuitar」)を定義しますが、KB2とは違った方法で定義しています。特に、「playsAirGuitar」述語を定義する3つのルールは、いくつかの新しいアイデアを導入します。まず、以下のルール
playsAirGuitar(vincent):-
listens2Music(vincent),
happy(vincent).
には、体部に2つの項目、または(標準的な用語では)2つのゴールがあることに注意してください。このルールは何を意味するのでしょうか?最も重要な注意すべき点は、「,」(コンマ)です(ルールの体部のゴール「listens2Music(vincent)」とゴール「happy(vincent)」を分離しているコンマです)。これは、Prologで論理積を表す方法です(すなわち、「,」は「and」を意味します)。したがって、このルールは以下のことを述べています、「ヴィンセントは、彼が音楽を聞き、彼が幸せであれば、エアギターを演奏します」。
したがって、以下の質問をした場合、
?- playsAirGuitar(vincent).
Prologは「no」と答えるでしょう。 KB3は「happy(vincent)」を含みますが、情報「listens2Music(vincent)」は明示的に含んでおらず、この事実はまた演繹することもできないためです。KB3は「playsAirGuitar(vincent)」の確立に必要な2つの前提条件のうち一方のみを満たすため、クエリは失敗します。
なお、このルールで使用される間隔は無関係です。例えば、以下のように記述したとしても、
playsAirGuitar(vincent):- happy(vincent),
listens2Music(vincent).
まったく同じことを意味します。 Prologは知識ベースを記述についてとても自由をであり、読み取り可能なコードを維持するために利用することができます。
次に、KB3は全く同じ頭部を持つ2つのルールを含んでいることに注意してください、すなわち、
playsAirGuitar(butch):-
happy(butch).
playsAirGuitar(butch):-
listens2Music(butch).
これはブッチは、彼が音楽を聞くか、または幸せであるならば、エアギターを演奏することを述べています。つまり、同じ頭部で複数のルールをリストした場合、論理和(つまり、「or」)を表わします。そのため、以下の質問の場合、
?- playsAirGuitar(butch).
Prologは「yes」と答えるでしょう。これらのルールの最初のものは助けになりません(PrologはKB3から「happy(butch)」を結論づけることはできません)が、KB3は「listens2Music(butch)」を含み、Prologはルール
playsAirGuitar(butch):-
listens2Music(butch).
を使用して前件肯定を適用し、「playsAirGuitar(butch)」を結論づけることができることを意味します。
Prologで和を表現する別の方法があります。単一のルールにより、上記のルールのペアを置き換えることができます。
playsAirGuitar(butch):-
happy(butch);
listens2Music(butch).
つまり、セミコロン「;」は「or」のためのPrologのシンボルであり、この単一のルールは、前述のルールのペアと全く同じことを意味します。では、複数のルールとセミコロンのどちらを使用するのが良いでしょうか?それが場合によります。一方で、セミコロンを広範に使用した場合Prologのコードは読みづらくなります。他方、セミコロンは、Prologが1つのルールのみ扱うだけでよいため、より効率的です。
Prologと論理の関係を明確にしましょう、結局、「:-」は含意を、「,」は論理積を、「;」は論理和を意味します。 (否定については?それはまったく別のストーリーです。第10章でそれを論じます。)また、標準的な論理証明規則(前件肯定)がPrologのプログラミングにおいて重要な役割を果たしていることを見てきました。そして私たちはすでに「Prolog」は「Programming with logic(論理によるプログラミング)」の略である理由を理解し始めています。
知識ベース4
KB4、第四の知識ベースは、次のとおりです。
woman(mia).
woman(jody).
woman(yolanda).
loves(vincent,mia).
loves(marsellus,mia).
loves(pumpkin,honey_bunny).
loves(honey_bunny,pumpkin).
さて、これはかなり退屈な知識ベースです。ルールがなく、事実の集合のみです。オッケー、引数として2つの名前を持つ関係(すなわち関係「loves」)は初めてですが、素直に受け入れましょう、それは予測できる考えです。
今回の目新しさは知識ベースではなく、これから行うクエリにあります。具体的には、初めて変数を使用します。例を示します。
?- woman(X).
Xは変数です(実際には、大文字で始まる任意のワードはPrologにおける変数です、これまでの例で最初の文字に小文字を使うように注意しなければならなかったのは、このためです)。変数は名前ではなく、情報のためのプレースホルダーです。つまり、このクエリは、Prologに以下を尋ねます、「知っている個人のうち、だれが女性か教えてください」。
Prologは、上から下までKB4を突き進み、KB4が含む情報と表現「woman(X)」を単一化(unify)(またはマッチ)する試みにより、この質問に答えます。今、知識ベースの最初の項目は、「woman(mia)」です。そのため、PrologはXを「mia」と単一化します、このようにクエリを完全に最初の項目に合致させます。 (ちなみに、このプロセスには異なる用語があります、PrologはXを「mia」に「インスタンス化(instantiates)」する、または、Xを「mia」に「結合(binds)」する、とも言います。)Prologは戻って以下の通り報告します。
X = mia
つまり、KB4に少なくとも一人の女性についての情報があることを述べるだけではなく、実際に彼女が誰であるかを教えてくれます。それはただ「yes」とは言わず、実際に成功につながった変数結合(または変数のインスタンス)を示してくれます。
しかし、これで終わりではありません。変数の重要な点は、別のものを、支持または単一化できるということです。知識ベースには他の女性についての情報があります。セミコロンを入力することにより、この情報にアクセスすることができます。
X = mia ;
「;」は「or」を意味することを思い出してください、クエリは次のことを意味します、「他のの選択肢がありますか?」そして、Prologは再び知識ベースを介して作業を開始し(Prologは前回どこで終わり、どこから始めるべきか覚えています)、Xをジョディに単一化した場合、クエリは知識ベースの2番目のエントリに合致することが分かります。そして、応答します。
X = mia ;
X = jody
KB4内に第2の女性についての情報があること、そして(再び)実際に成功につながった値を教えてくれます。そしてもちろん、再び「;」を押した場合、Prologは答えを返します。
X = mia ;
X = jody ;
X = yolanda
しかし3度目「;」を押すと何が起こるでしょうか? Prologは「no」と答えます。他の単一化は不可能です。シンボル「woman」で始まる他の事実はありません。知識ベースの残りの4つのエントリは愛の関係に関しますが、それらのエントリには、「woman(X)」の形式のクエリに単一化できる方法がありません。
より複雑なクエリを試してみましょう。
?- loves(marsellus,X), woman(X).
「,」が「and」を意味することを思い出してください、このクエリは次の意味です、「マーセラスがXを愛し、かつ、Xが女性であるような、人物Xはいますか?」知識ベースには以下があります、「ミアは女性(事実1)であり、マーセラスはミアを愛している(事実5)」。そして実際、Prologはこれを解くことができます。つまり、知識ベースを検索し、Xをミアと単一化した場合問合せの両方の論理積は満たされる、ということを解くことができます(Prologがどのようにこれを行うかについては、次の章で学びます)。そして、Prologは答えを返します。
X = mia
知識ベースの情報と変数を単一化する作業は、Prologの核心です。これから学ぶように、Prologには多くの興味深いアイデアがありますが、結局のところきわめて重要なのことは、単一化を行い変数結合の値を返すことができるという、Prologの能力です。
知識ベース5
さて、私たちは変数を導入してきましたが、今のところ、クエリで使用するだけでした。しかし、変数は知識ベースで使用できるだけでなく、本当に興味深いプログラムを書くには、変数を使用しなければなりません。単純な例、知識ベースKB5は以下のとおりです。
loves(vincent,mia).
loves(marsellus,mia).
loves(pumpkin,honey_bunny).
loves(honey_bunny,pumpkin).
jealous(X,Y):- loves(X,Z), loves(Y,Z).
KB5は「loves」の関係に関する4つの事実と1つのルールを含みます。(ちなみに、事実とルールの間の空白行に特に意味はありません、単に読みやすくするためです。前述したとおり、Prologは知識ベースをフォーマットする上で多く自由があります。)しかし、このルールはこれまでよりはるかに興味深いものです、それは3つの変数を含みます(X、Y、Zはすべて大文字であることに注意してください)。このルールは何を述べているのでしょうか?
実質的に、嫉妬の概念を定義しています。これは、ある人物Xが愛している人物Zがいて、人物Yも同じくZを愛している場合、XはYに嫉妬する、と述べています。 (オッケー、現実世界の嫉妬はこれほど単純ではありません)注意すべき重要な点は、これが一般的命題であることです。ミアに関して述べているわけではなく、パンプキンでも、特定の誰かについて述べているわけでもありません、それは私たちの身の周りのあらゆる人物に関する条件文です。
以下のクエリをしたとしましょう。
?- jealous(marsellus,W).
このクエリは、「マーセラスが嫉妬するような人物Wを見つけることができますか?」と問合せます。ヴィンセントは、そのような人物です。嫉妬の定義を確認してください、マーセラスはヴィンセントに嫉妬しなければなりません、なぜなら二人とも同じ女性、すなわちミアを愛しているからです。そのため、Prologは値を返します。
W = vincent
あなたにいくつか質問します。まず、KB5の中に他に嫉妬深い人がいますか?さらに、Prologに嫉妬深い全ての人について教えて欲しいと思ったとします。どのようなクエリをすれば良いでしょうか?答えのいずれかはあなたを驚かせるでしょうか?何か、愚かに思いますか?