一時はSCBMを諦めました。あまりにも複雑すぎるのではないか?
根本的にこの計算モデルは機能しないのではないか?
翌日になって閃きました。あんがいと単純なことだったのでは?
アニメ宇宙戦艦ヤマトでは劇中、最後の最後になって敵方のデスラーがヤマトに乗り込み白兵戦を展開します。
ヤマト絶体絶命か?とそのときにコスモクリーナが作動したのでした。
私も最後の望みをこれに託そうと思います。これでだめなら私には手に負えない。
いつのも例
select1(X,[X|Xs],Xs).
select1(X,[Y|Ys],[Y|Zs]) :-
select1(X,Ys,Zs).
perm1([],[]).
perm1(Xs,[X|Ys]) :-
select1(X,Xs,Zs),
perm1(Zs,Ys).
select1が強制バックトラックしたときに再帰先のperm1は正しく変数ポインタが回復しないのが問題でした。
アイディア
思いついたアイディアは単純です。再帰においても成功継続を生成してそこで変数ポインタを回復させるというものです。
select1(X,[Y|Ys],[Y|Zs]) :-
select1(X,Ys,Zs). <===ここに成功継続を生成する
再帰が終了したあとどこへ飛ぶのか?ここがかねてから疑問でした。試行錯誤ののちに
再帰においては成功継続は要らないのではないかと思っていました。制御構造だけを考えればそれで正しいのですが、それでは変数ポインタが回復しないことに気が付きました。
変数ポインタを回復させる成功継続を成功スタックに積んで再帰をスタートします。
戻るときにはその成功継続により順次変数ポインタは復元されます。
途中においてバックトラックがあった場合には失敗継続からその直前の変数ポインタを復元して別解をさがしそれが成功した場合には成功継続に進むことにより変数ポインタが復元されます。
バックトラックにより失敗した場合には失敗継続を起動することにより成功継続のポインタが失敗時の値に復元されます。これにより再帰のためにつまれた成功継続は廃棄されます。
さてこれで解決するだろうか?私にはこれが正解のように思えるのですが実証試験をしてみないことにはなんとも言えません。もしこれでうまくいくようなら割と簡単な計算モデルでPrologの実行をC言語に置換することができます。
さあ、どうなることでしょう。