kprolog K-Prolog Compiler Version 6.0

コンパイラとローダ

インタプリタやデバッガで開発したプログラムを高速化したいときは、 コンパイルすることができます。

コンパイラは、 compile組込み述語として実現されています。
compileは、plccコマンドによってProlog言語のプログラムをC言語に変換し、 さらに、Cコンパイラによってオブジェクトモジュールを作成します。
従って、Cコンパイラは指定のものがあらかじめ用意されていなければなりません。

K-Prologコンパイラのコンパイル単位はモジュールを含むファイルです。 ファイルの中には、モジュール宣言が必要です。 通常は1モジュール/1ファイルの構成です。

コンパイラは、コンパイル単位内のモジュールに対し、 それぞれ

という名前のファイルを作ります。 また、コンパイルオプションの指定により、 も生成されます。
同じ名前のモジュールをコンパイルしたときは、 後からコンパイルした方が残ります。

モジュール名.o には、C言語の関数としてコンパイルされた述語がはいっています。 述語名は _Nname() の形で、Nは数字で述語のアリティをあらわします。
publicな述語はC言語での外部シンボルとなり、 publicでない述語は static な関数となります。
述語がC言語の名前として不適当ならば、別の名前につけ変わります。

モジュール名はC言語の関数名として適切な名前でなければなりません。
モジュールを初期化する関数として 'モジュール名()' が作られるからです。 英字,_と数字から成り、先頭が英字ならばモジュール名として使用できます。 '_'で始まるモジュール名は予約されていますから使わないで下さい。 モジュール'public'は処理系が使用しています。
また、モジュール名はC言語のライブラリの関数名と同じであってはなりません。 したがって、mainやread など多くの使えない名前があります。

ローダは組込み述語 load_compiled_modules として実現 しています。 load_compiled_modules は、 1つまたは複数の .oファイル(または.obj)を結合し、 開発環境内に読み込み、実行できるようにします。 この操作をインクリメンタルローディングと呼びます。 このさい必要に応じて、UNIX 環境の場合は新しい .o ファイルが、 Win32環境の場合は DLL ファイルが生成されます。

[例]

   19: ?- compile(list.pl).
          ・
          ・
          ・
     コンパイル・ログ
          ・
          ・
   20: ?- load_compiled_modules(list).

コンパイラによって生成されたオブジェクトモジュールを結合して 別のロードモジュールを生成することもできます。 インストールディレクトリにありますMakefileをコピーして利用して下さい。 Makefileの編集方法はC言語インタフェース と同じです。
新しく作られたロードモジュールはK-Prologの組込み述語の他に コンパイルされた述語が組み込まれています。


最適化

K-Prologコンパイラは次のような最適化を行なうことによって、 実用レベルのコンパイルコードを生成することに成功しています。
末尾再帰の除去 (Tail Recursion Elimination)
末尾再帰に関して、自分自身を呼び出すゴールが節の最後にあって、 かつ、節の決定性がコンパイル時にわかるときに、再帰から繰り返しへの変換を 行ないます。
末尾ゴールの平坦化(Last Call Optimizaiton)
決定的な節の最後のゴールはスタックを平坦化して実行されます。 この機能によりスタック消費量を減らしています。
述語モードの自動生成(Mode Generation)
モジュール内の述語に対し、その呼びだし経路をすべて計算し モード宣言を自動生成します。
コンパイル時疑似実行による簡約化(Reduce)
コンパイル時にモードを生成するだけでなく述語を疑似実行することによって ゴールを簡約化します。
この手法により決定的な述語を劇的に効率改善できる場合があります。
インデキシング(Indexing)
述語の節の個数が多くかつ、 節の特定の引数がすべてアトムまたは複合項または小さな整数で 値の重複が少ないとき、節への高速なアクセスを可能にするために 2分探索によるインデキシングコードが生成されます。この インデキシング計算はすべての引数に対して行なわれます。
テーブル化(Tabulation)
インデキシングが行なわれるような状況では節の引数を 配列に保存することによってコードを小さくできることがあります。 実行速度を僅かに犠牲にすることによってメモリの節約を計っています。


一つ上に戻る 目次に戻る