編集
これは毛むくじゃらになっており、私の答えはリクエストを正確に説明していませんでした...最小限の変更でコードを見てみましょう:
concat([], L, L).
concat([H|T], L, [H|Res]) :-
concat(T, L, Res).
repl([], _, _, []).
repl([Val|T], Val, Repl, Res) :- !, % as noted by @repeat, better to commit early...
repl(T, Val, Repl, Temp),
concat(Repl, Temp, Res). % !.
repl([H|T], Val, Repl, [H|Res]) :-
repl(T, Val, Repl, Res).
カットは単に2番目の句をコミットします...
古い回答を再開する
concat/3 はよく知られている append/3 と同じなので、このアプローチを検討してください
repl(ListOrig, Element, Replace, ListUpdated) :-
append(H, [Element|T], ListOrig),
append(H, Replace, Temp),
append(Temp, T, ListUpdated).
?- repl([1, 2, 3], 3, [2, 3, 4], L).
L = [1, 2, 2, 3, 4] ;
false.
編集
コメントで要求されているように、この拡張機能は、単純なパターン マッチングを使用して、変更に一致する要素のリストを処理します (注: 前の句の前に追加します)。
repl(ListOrig, [], _Replace, ListOrig).
repl(ListOrig, [E|Es], Replace, ListUpdated) :-
repl(ListOrig, E, Replace, Temp),
repl(Temp, Es, Replace, ListUpdated).
テスト
?- repl([1,2,3],[2,3],[x,y,z],R).
R = [1, x, y, z, x, y, z] ;
false.
編集
Element が見つからなくても失敗しないことに気づきませんでした...最後の「catchall」句でこのケースを処理できます。
repl(ListOrig, _Element, _Replace, ListOrig).
またはそれ以上に、元のように拡張します
repl(ListOrig, Element, Replace, ListUpdated) :-
( append(H, [Element|T], ListOrig)
-> append(H, Replace, Temp),
append(Temp, T, ListUpdated)
; ListOrig = ListUpdated
).