いろいろな組み込み関数


12.1 項の型チェック

項には定数、文字定数、変数、構造などの型がありました。また、変数は実行中のある時点においてユニファイされて具体的な値が代入されているか、または代入されていないかのどちらかの状態が考えられます。ということは、変数がユニファイされていれば、その変数の具体的な値にも型があるわけです。

そのような項の型が判ると便利です。また、整数かどうかも判ると便利です。例えば、エラーチェックを考えてください。ある変数が整数なら続けて処理を行うが、整数でなければメッセージを出力するなどの処理をしたい場合などです。このようなチェックを行う関数には次のようなものがあります。 さて、アトムとは何でしょう。これは、いままで私たちが「文字定数」と呼んできたものなのです。正確には「アトム」と「文字定数」とは微妙なニュアンスの違いがあるのですが、まぁ、いっしょと考えても差し障りありませんので、皆さんには馴染みのある「文字定数」という言葉を使ってきました。今後も学習を続けていく際には「文字定数」でも構いません。ただ、Prolog関係の本を読んだり、また今回のような型チェックの関数を使う場合には「文字定数」=「アトム」と置き換えて考えてください。



《演習問題》

12.2 項の組立と分解

新しい項を作ったり、項を分解したりする関数があります。



《演習問題》

12.3 項の等価

前に算術計算で数の比較について学習しました。一般に比較するのは数の場合が多いのですが、文字定数や構造を比較したい場合もあります。そこで、項が等しいかどうかを比較するものとして、次の記号を用います。 =:=と==と=とが混乱しないよう注意してください。例を挙げておきます。
          ?- f(a,b) == f(a,b).
          yes

          ?- f(a) == f(X).
          no

          ?- g(f(X)) == g(f(X)).
          yes

          ?- X \== Y.
          yes

          ?- f(a,b) = f(a,b).
          yes

          ?- f(a) = f(X).
          X = a
          yes

12.4 データ処理

磯野家の家族関係のようなデータベース的な処理はPrologの得意なものの一つです。磯野家の家族関係の場合は、必要な節は全てファイルに記述しておいて、質問をプロンプトから入力しました。でも、プロンプトから節を入力したいこともあるかもしれませんし、実行中に条件によって節を増やすという操作をプログラムの中に書きたいこともあるかもしれません。逆に、節を削除したいこともあるでしょう。そのような処理を行う関数には次のようなものがあります。 先ず、簡単な具体例を示しましょう。
          ?- holiday.
          no

          ?- assert(holiday).
          yes

          ?- holiday.
          yes

          ?- retract(holiday).
          yes

          ?- holiday.
          no
途中でlisting.と入力してインタプリタに読み込まれているプログラムの内容を確認すると一層判りやすいでしょう。

次に、もう少し複雑な例を示します。以下のプログラムがあって、インタプリタに読み込まれているとします。
          nice:-
              holiday,\+(school).
          mistake:-
              holiday,school.
          hard:-
              school,study.
          school.
          study.
このプログラムとは、以下のような対話ができます。
          ?- nice.
          no

          ?- hard.
          yes

          ?- retract(study).
          yes

          ?- hard.
          no

          ?- assert(holiday).
          yes

          ?- mistake.
          yes

          ?- retract(school).
          yes

          ?- nice.
          yes
更にもう少し複雑な例を示します。遊幽のときに次の節がありました。
          tall(yuusuke).
          small(genkai).
          small(koenma).
          tall(kurama).
          small(hiei).
このプログラムに次のようにルールを加えてみましょう。
          ?- assert((taller(X,Y):-tall(X),small(Y))).
          yes

          ?- taller(A,B).
          A=yuusuke
          B=genkai

          ?- abolish(small).
          yes

          ?- taller(yuusuke,_).
          no
これらの関数については、もっと気の利いた使い方もできます。ルールにマッチングさせて答えを出すより、予め答えの節を作成しておいた方が操作する場合に速いに決まってます。そこで、次のプログラムを考えます。
          kukutable:-
              member(X,[1,2,3,4,5,6,7,8,9]),
              member(Y,[1,2,3,4,5,6,7,8,9]),
              Z is X * Y,
              assert(kuku(X,Y,Z)),
              fail.
failは強制的に失敗させるという命令です。つまり、assertを実行した後で必ず失敗するということで、ここでバックトラックを生じさせるのです。実際にどのように動くのかはトレースしてみてください。このプログラムを読み込んで実行します。
          ?- kukutable.
これは勿論成功しませんが、実行の過程でどんどんkukuの節をassertしていきます。このようなプログラムの成功・失敗に関わらず行われる処理を{\gt 副作用}と呼びます。上のプログラムで掛け算のデータベースを作成すると、次のように掛け算の結果を求めたり、特定の値になる九九を求めることができます。
          ?- kuku(3,4,X).
          X=12

          ?- kuku(6,X,12).
          X=3

          ?- kuku(X,Y,12).
          X=2
          Y=6;

          X=3
          Y=4;

          .....




《演習問題》

12.5 プログラムの制御

前節でfailを使って強制的に失敗させるというのをやりました。これによって結果的にループを実現したわけです。処理の流れを制御する目標には以下のようなものがあります。 実は、Prologの処理の制御には奥深いものがあります。(判りやすく言うと、とても難しいってことね)カットを用いたバックトラックの抑制に関しては、ここではあまりつっこまないでおきましょう。(学生諸君の学習意欲を阻害するつもりはありませんが、なにせ「記号論理学」の単位は2単位しかないから。ここで上っ面だけの理解になったにしても、最後のプロダクションシステムまで進んで欲しいから。もっと頑張りたい人は申告してください。別途対応しましょう)

repeatとカットに関しては以下の典型的な処理だけは理解しておくようにしてください。
          条件が成立するまで処理を繰り返す
          repeat,処理,条件,!.

          file_read:-
              repeat,
              read(X),        % 処理
              write(X),nl,    % 処理
              X == stop,      % 条件
              !.




《演習問題》

12.6 該当者を捜せ

いろいろな組み込み関数を取り上げてきました。最後に、ある条件に該当する節をピックアップする関数を紹介します。データ処理を行うときに重宝します。 これらは例を参照した方が判りやすいでしょう。例えば、次のように使います。再び遊幽で、
          tall(yuusuke).
          small(genkai).
          small(koenma).
          tall(kurama).
          small(hiei).
でしたね。ここで背の低い人(?)だけピックアップしてみましょう。
          ?- bagof(Person,small(Person),List).
          List=[genkai,koenma,hiei]
Listはsmall(Person)を成立させる、即ちsmall(Person)という節が存在するようなPersonのリストということになります。では、目標Pの引数が2つ以上のときはどうなるのでしょう。磯野家で例を示します。
          ?- bagof(Person,parent(Person,_),List).
          List=[namihei,fune,sazae,masuo,umi]




《演習問題》
目次に戻る目次に戻る