はじめに
SCBM方式によるProlog処理系の実装が、ようやく形になってきました。
SCBM(Sasagawa Continuation Backtracking Model)は、従来のWAMとは異なるアプローチでPrologの実行機構を実現する計算モデルです。
開発を進めるなかで、SCBMを単なる実装方式にとどめず、独自の言語仕様を持つProlog処理系としてまとめたいと考えるようになりました。
その基本方針は、シンプルで理解しやすく、実装しやすい言語仕様です。
1. 基本的な考え方
Prologは、もともと一階述語論理を基礎とするプログラミング言語です。
しかし、実用的なプログラミング言語として発展する過程で、さまざまな機能や拡張が加えられてきました。その集大成の一つがISO Prolog規格だと思います。
もちろん、こうした拡張にはそれぞれ理由があり、実用上の価値があります。しかし、機能を増やすことが必ずしも言語の使いやすさにつながるとは限りません。
そこでSCBM-Prologでは、ISO Prologの機能をすべて実装することを目標とはせず、本質的で実用性が高いと考える機能を選び、無理なく実装できる範囲に仕様を整理する方針です。
参考にするのは、DEC-10 PrologやARITY/PROLOGです。
これらの古典的なPrologが持っていた簡潔さを大切にしながら、現代的な処理系として再構成したいと考えています。
2. 選言のネストを認めない
具体例として、選言(;)の扱いを説明します。
次のような単純な選言は認めます。
(a ; b)
一方、次のようなネストした選言は仕様から除外します。
((a ; b) ; (c ; d))
選言をネストすると、バックトラックの制御構造が複雑になります。また、プログラムを読む人間にとっても、実行の流れを追いにくくなります。
SCBMでは、選言を次のような無名述語オブジェクトに変換する方法を採用します。
anonymous_pred :- a.
anonymous_pred :- b.
これは概念的な表現ですが、選言に対応する述語オブジェクトを生成し、それをSCBMの証明列に挿入することで実行します。
選言のネストを認めなければ、この仕組みは比較的簡潔に実装できます。
複雑な構文を許容するよりも、単純な構造を組み合わせてプログラムを記述する方針です。
3. 高階述語の制限
高階述語についても、同様の方針を採用します。
例えば、call/1 は次のように使用できます。
call(p)
しかし、連言や選言を引数として渡す形式は認めません。
call((p, q)) % NG
call((p ; q)) % NG
call/1 の引数は、単一の述語呼び出しに限定します。
これによって、高階述語の処理を簡潔に保つことができます。
同様に、REPL(対話型実行環境)においても、質問は単一の述語呼び出しに限定します。
?- parent(tom, X).
これは認めますが、次のような連言を直接入力する形式は認めません。
?- parent(tom, X), parent(X, Y).
複数の述語を組み合わせたい場合には、あらかじめプログラム中に述語として定義します。
これにより、REPL自体の実装も単純になります。
4. カットの扱い
Prologのカット演算子(!)は、探索を制御するための重要な機能です。
しかし、カットは使用方法によってプログラムの意味やバックトラックの挙動を理解しにくくすることがあります。
SCBM-Prologでは、実用上必要な範囲に用途を限定し、複雑なネスト構造などは仕様から除外する方針です。
SCBM方式では、カットの実装は比較的直感的です。
SCBMは、証明木を双方向リストによる証明列として表現しています。
カット演算子に到達したら、その述語の呼び出しに対応する所定の位置まで証明列をたどり、不要になった選択肢を含む部分を切り離し、残りの証明列をつなぎ合わせます。
文字どおり、証明列をカットするわけです。
このように、Prologの制御構造を証明列の操作として直接表現できることが、SCBM方式の特徴の一つです。
5. 言語仕様と実装の関係
SCBM-Prologでは、言語仕様と実装方式を切り離して考えるのではなく、両者の整合性を重視します。
言語仕様が簡潔であれば、コンパイラや実行系も簡潔になります。
そして、実装が簡潔であれば、動作の検証やバグの発見、性能改善も容易になります。
特にSCBMでは、コンパイラが生成するコードと証明列による計算モデルとの対応関係を、できるだけ明瞭に保ちたいと考えています。
複雑な機能を追加するために実行機構を肥大化させるのではなく、計算モデルの特徴を自然に生かせる範囲で言語機能を整備していきます。
6. まとめ ― 人間のための言語仕様
プログラミング言語の設計には、できるだけ制限をなくし、表現力を高めようとする考え方があります。
それも一つの方向性でしょう。
しかし、忘れてはならないのは、プログラムを書くのも、読むのも、理解するのも人間であるということです。
複雑な構文や制御構造は、言語の表現力を高める一方で、プログラマーの認知的な負担を増やし、思わぬミスを誘発することがあります。
私が目指しているのは、何でもできるPrologではありません。
必要十分な機能を備え、仕組みを理解しやすく、自分の頭で実行の流れを追えるPrologです。
かつてCommon Lispに対して、簡潔で整理された言語仕様を目指すISLispが制定されました。
SCBM-Prologも、それに似た発想で設計を進めたいと考えています。
機能の多さよりも、仕組みの明快さを大切にする。
これがSCBM-Prologの言語設計における基本方針です。