редактировать
это становится волосатый, и мой ответ не приходилось именно по просьбе ... так что давайте посмотрим код с минимальным изменения:
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).
разрез просто фиксирует второе предложение ...
резюме старый ответить
ваш 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.
редактировать
я не заметил, что если элемент не найден он не должен терпеть неудачу ... последний «всеобъемлющая» положение может обрабатывать этот случай:
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
).
разрез должен пойти после Concat/3 вызова: 'CONCAT (Repl, Temp, Res), .' – CapelliC
@CapelliC. Не стойкий! ** Если ** мы должны использовать cut, тогда мы лучше сделаем это так: 'repl ([Val | T], Val, Repl, Res): -!, Concat (Repl, Temp, Res), repl (T , Val, Repl, Temp) .' – repeat
Пожалуйста, будьте более конкретным! Какой ответ (ы) вы ожидаете для '? - repl ([x, y, x, y, x], x, [x, y, x], L) .' – repeat