このディレクトリの索引

#  member/2を成功裡に追えるテクニックとして
#  append/3を使う方法があることは書きました。
#  ?- append(_,[A|R],[1,4,2]),
#     writef('%t\n',[A]),
#     R = [].
#  1
#  4
#  2
#  true.
#  となるでしょう。
#  
#  このmember/2 の代わりに append/3を使うことには重大な
#  落し穴があります。

test :-
        append(_,[A|R],[1,4,2]),
        writef('%t\n',[A]),
        R = [].

?- test.
1
4
2
true. となりますが、

test :-
        append(_,[A|R],[1,4,a]),
        integer(A),
        writef('%t\n',[A]),
        R = [].

?- test.
1
4
false.

%  となってしまいます。R = [] より前で integer(a) がfailになるため
%  R = []. に到達しないのです。しかも失敗するのが、最後の要素である場合だけ、
%  顕在化します。ここでも成功裡に終わりたいなら
%  

test :-
        append(_,[A|R],[1,4,a]),
        integer(A),
        writef('%t\n',[A]),
        R = [],!.
test.

%  としなくてはなりません。R = [], の後のカット(!)も不気味ですね。
%  
%  結論としては、member/2の代わりで、しかもappend/3のRを終止条件の判断に使って、
%  安全に成功裡に終了するためには、append/3と R = [],の間は副作用など
%  安定して true になる副目標だけで構成されている必要があるということです。
%