next up previous contents index
Next: 述語の原則 Up: コンパイルドコード Previous: モジュールの原則

  
述語呼び出しの実現

           

述語の呼び出しは、大別して、以下の2通りの実装がある。

通常呼び出し:
KLICでは述語を呼び出すためには、基本的に、

1.
ゴールレコードを作成し、そこに述語情報、引数情報を書きこみ、 ゴールスタックにエンキューする。これを必要な回数繰り返す。

2.
実行している述語が終了したならば、ゴールスタックより ゴールをデキューして、その述語を次の実行対象にする。

という手続が行われる。

直接呼び出し:
上記のような呼び出し手続を行う場合、 基本的には、直前にエンキューした述語をデキューし実行することになる。 よって、ゴールレコードのエンキューとデキューとが連続する場合には、 ゴールレコード作成、エンキュー、デキューという処理を介さずに 直接実行対象とするという最適化が考えられる。 これを直接呼び出しと呼ぶ。

KLICでは、中断がなければユーザが記述した順にゴールを実行するように コードを出力する。そのために、ユーザが記述した順と逆の順でゴールを 準備し、エンキューしていくようなコードが出力される。よって、 上記の直接呼び出しの最適化が行われる対象となるゴールは 最後にエンキューされたゴール、すなわち、最初に記述された ゴールであり、この最適化をFGO(First Goal Optimization)と呼ぶ。

このFGOは、呼び出し側と同じ述語と同じモジュールに対しての呼び出しに対してのみ 行っており、この場合には、Cのgoto 文によるジャンプ が出力されるようになっている。 C言語では他の関数の中間に飛び込む、という機能はないため、 「最初に記述されたゴール」が他モジュールの場合にはFGO最適化を行わず 通常呼び出しを行う。

また、以上のような最適化を行っているため、例外的な場合 ([*]ページ、第3.4章参照)を除き、当該モジュールだけで実行されている間は この関数からreturnはされない。

なお、通常呼び出しのデキュー処理は、preceed()なるマクロで実現されている。  また、直接呼び出しはexecuteなるマクロで実現されている。  



Sekita Daigo
1998-05-18