Prologの基本的なデータ構造

「Prologの基本的なデータ構造」の編集履歴(バックアップ)一覧はこちら

Prologの基本的なデータ構造」(2014/05/07 (水) 12:26:12) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

**Prologの基本的なデータ構造 -単位節について   Prologの基本単位は「項(term)」と呼ばれます。   項は&bold(){単純項}と&bold(){複合項}に分類されます。   さらに単純項は&bold(){定数}と&bold(){変数}があります。 -定数 定数はプログラムの実行中に値は変化せずに一定です。 定数には数とアトムがあります。 数 ・・1234など アトム・・abc、山田、'XYZ'など -変数 変数はプログラムの実行前に、自身の値が定まっていない項です。 プログラムの実行中に値が決まります。 (1)英大文字で始まる任意の文字列 ・・・XYZ (2)アンダーラインで始まる任意の文字列 ・・・_山田    -複合項 複合項は項をいくつか組み合わせてできた項です。 述語(アリティ、・・). ※Prologでは引数のことをアリティを呼びます。 ---- ***単位節を使ってみよう(その1) a(1). test:- a(X),write(X). ?-test. 1 ・3つのルール   上記の実行例で、[test:-・・・]の記述がありますが、これはPrologにおいて「規則」と呼ばれます。   また[?-test.]は「質問」と呼ばれ、記述した述語を実行するルールです。    Prologには「事実」「規則」「質問」の3つのルールを用いて知識を表現できます。 事実・・・a(1). 規則・・・test:- a(1). 質問・・・?-test. ---- ***ユニフィケーションについて   test述語を実行した際、a(X)が実行されます。   その際、単位節[a/1(/1はアリティ数)]が実行され、X変数に[1]が代入されます。   この仕組みを、ユニフィケーションと呼びます。 ---- ***単位節を使ってみよう(その2) 1 a(1,2). test:-a(X,_),write(X). 1 2 a(X,Y). test:-a(X,Y),write(X=Y). _10=_11  ※単位節[a(X,Y)]には定数ではなく、変数が定義されてますので、   test述語を実行した際、a(X,Y).から取得した値は未定義(変数)のため   write述語で実行した結果、未定義の値が出力されます。   よって、必ずしも[_10=_11]といった値にならないことに、注意してください。 3 a(1). a(1,2). %こちらの単位節が呼ばれる test:-a(X,_),write(X). 1 4 a(1,2). a(3,4). test:-a(X,_),write(X). %a(3,4).は実行されない。 1  上記4の実行時、単位節「a/2」の中で、a(1,2)の単位節のみ実行された。  a(3,4).も表示したい場合は、どうするか?  ここで&bold(){バックトラック}というPrologの特殊な機能を使用します。 ---- ***バックトラックについて  バックトラックとはプログラム実行時、ある述語の別解を求めるための制御構造です。 a(1). a(2). ?-a(X),write(X),nl. %nlは改行する述語です 1;・・・ここで[;]と打ちEnterを押し別解を求める。 2; no  単位節[a/1]の解を質問によって求めた際、まずa(X)のXには[1]がユニフィケーションされ  X=1が解として出力されます。この際、セミコロン[;]を入力しEnterを押すと、[1]の別解を  求められ(バックトラックし)、[2]がユニフィケーションされ、X=2が出力されます。  またX=2が出力された後、もう一度バックトラックさせると、他の解は存在しないため、[no]と  表示し終了します。    別解を求めるたびに、[;]を入力するのは手間なので、自動的にバックトラックをさせる述語がPrologには存在します。  それが[&bold(){fail}]という述語です。 a(1). a(2). ?-a(X),write(X),nl,fail. 1 2 no これで、上記4の実行例において、a(3,4)を表示する方法が理解して頂けたかと思います。 4・(改修) a(1,2). a(3,4). test:-a(X,_),write(X),nl,fail. %failでバックトラックさせる test:-!. 1 3 yes ---- ***カットオペレータについて バックトラックを使って、a/2単位節のすべてのデータを表示する仕組みを説明しました。 しかし、プログラムの制御によってはある単位節のデータを処理した後は、その後の データは必要なく、処理をしてほしくない場合があるかと思います。 その際に、使うPrologの述語が「!(カットオペレータ」です。 例を示します。 a(1). a(2). a(3). test:- a(X),write(X),nl,fail. という事実と規則を定義した場合、test述語を実行すると、単位節[a/1]のデータが すべて出力されることは、先ほど学習しました。 ではa(2)を出力した後は、a(3)を出力したくない場合は、どのようにすればよいか。 以下の用にカットオペレータを使います。 a(1). a(2):- !. a(3). test:- a(X),write(X),nl,fail. では実行してみます。 ?-test. 1 2 期待した出力結果が出ましたでしょうか? バックトラックを制御する際に、カットオペレータは使用しますので、 覚えておいてください。 ---- ***単位節を使ってみよう(よくある間違え)  単位節で、  a('A').  b('B').  c('C').  という事実があり、それぞれの値を表示する場合は、どうすれば良いでしょうか?   よくある間違えとして、こういう実装をしてしまう場合があります。 test:- a(X),write(X),nl, b(X),write(X),nl, c(X),write(X),nl. ?-test. A no.  上記の述語を実行してみると、Aのみが出力され、その先は実行されずfailしました。  これは何故でしょうか?  実はPrologにおいて、変数は1度しかユニフィケーションされません。  よって、a(X)でXの値が['A']にユニフィケーションされた後、b(X)が実行されますが  これは[b('A')]を実行された事と同一になります。  b('A')の単位節は存在しない(定義されていない)ため、failされたため、上記の通りの  実行結果となりました。  a,b,cのすべてのデータを表示するには下記のようになります。 test:- a(X),write(X),nl, b(Y),write(Y),nl, %X以外の変数 c(Z),write(Z),nl. %X、Y以外の変数 ?-test. A B C yes.  これで、a,b,cのすべての単位節のデータが表示されました。 ---- ***まとめ 今回は以下の事を学習しました。 ・Prologのデータ構造(単純項、複合項など) ・ユニフィケーション ・バックトラック ・カットオペレータ ここはPrologを扱うにおいて、基本的なことなので身に着けておいてください。

表示オプション

横に並べて表示:
変化行の前後のみ表示: