@chamini2 によって提供された実装は不純であり、根拠のない用語を扱うと論理的に不健全になる可能性があります。次の 2 つのクエリを検討してください。
?- E=1、remove_first_X(E,Xs,[2,1,0])。
E = 1、Xs = [1,2,1,0] ;
E = 1、Xs = [2,1,1,0] ;
間違い。
?- remove_first_X(E,Xs,[2,1,0]), E=1 .
E = 1、Xs = [1,2,1,0] ;
間違い。% 1 つの解がありません!
prolog-difが助けてくれます!
に置き換える(\=)/2
とdif/2
、コードは論理的に純粋になります。
remove_1st_x(X,[X|Xs],Xs).
remove_1st_x(X,[Y|Xs],[Y|Ys]) :-
dif(X,Y),
remove_1st_x(X,Xs,Ys).
上記のクエリをもう一度実行してみましょう。今回は改善された実装を使用します。
?- E=1、remove_1st_x(E,Xs,[2,1,0])。
E = 1、Xs = [1,2,1,0] ;
E = 1、Xs = [2,1,1,0] ;
間違い。
?- remove_1st_x(E,Xs,[2,1,0]), E=1 .
E = 1、Xs = [1,2,1,0] ;
E = 1、Xs = [2,1,1,0] ;
間違い。
その方がいいです!また、OP によって指定された他のクエリも、次のように機能します。
?- remove_1st_x(1,[1,2,3],[2,3]).
true ;
false.
?- remove_1st_x(1,[2,1,3],[2,3]).
true ;
false.
?- remove_1st_x(1,X,[2,1,0]).
X = [1,2,1,0] ;
X = [2,1,1,0] ;
false.
編集 2015-05-07
上記の実装は、remove_1st_x/3
決定論的に成功する可能性がある場合に、役に立たない選択ポイントを残します。論理的純粋性を維持しながら、その非効率性を取り除きましょう!
質問「Prolog union for AUBUC 」への回答で@falseによって定義されているように、if_/3
等式(=)/3
(別名equal_truth/3
)を使用して具体化すると、次のように定義できます。remove_1st_x/3
remove_1st_x(E,[X|Xs],Ys) :-
if_(X=E, Xs=Ys, (Ys=[X|Ys0],remove_1st_x(E,Xs,Ys0))).
上記のクエリをもう一度実行してみましょう。すべてが決定論的に成功することに注意してください。
?- remove_1st_x(1,[2,1,3],Ys).
Ys = [2,3].
?- remove_1st_x(1,[2,1,3],[2,3]).
true.
?- remove_1st_x(1,[1,2,3],[2,3]).
true.