10月20日を目標にしてSCBM方式を改良を重ねてきました。
どうも複雑すぎてだめかもしれないと半ばあきらめてしまったのですが。
まてよ!
バグを見つけました。そして再帰における改善策も。
バックトラックは動的
p(X) :- q(X),r(X).
ここでq(X)が再帰述語だとします。強制バックトラックの可能性があります。
このとき制御を戻すのは直前におきた非決定性述語です。つまりバックトラック制御は
動的です。
変数ポインタは静的
一方で変数は静的です。1つの節の本体部においては変数は一貫していないといけません。
p(X) :- q(X),r(X).
Xは同じものを指していないといけません。しかしq(X)がバックトラックすると変数ポインタが動いてしまいます。そこでq(X)のもともとのオリジナルな変数ポインタをback_stackに記憶しておきます。C言語などの関数であればそのことは自然にできるのですが、SCBMでは手動でやらないといけません。バックトラックしたときには動的に制御を戻すとともにそれが終わったらもともとのオリジナルな変数ポインタにもどしてやらないといけません。back_stackからオリジナルな値を探し出します。そして以後はそれが成功継続に伝播されます。
バックトラックから変数ポインタを復元したあとは成功継続によりそれを伝播すればよかったのですが
ここにバグを持ち込んでいました。
再帰
再帰においても各説の本体部の変数は一意でなければいけません。再帰がやっかいなのは
再帰からもどったときには変数を前の呼び出し元の本体部と整合性がとれるように復元しないといけません。
再帰が成功したときには同様にオリジナルな変数ポインタに復元する必要がありました。
このことを失念していました。
仕事でつかれた頭はこれらのことが複雑にみえていました。しかしよくよく考えてみると自然なことには違いありません。
そしてその方法はシンプルに実現できることはわかっています。あと8日あります。いましばらく挑戦してみましょう。