What about:
replace(A, B, X, Y) :- ( X == A -> Y = B ; Y = X ).
Example:
?- maplist(replace(1,x), [1,2,3], Ls).
Ls = [x, 2, 3].
It is easy to unfold the maplist/3
call into a recursive predicate if you prefer that.
Pergunta
I am writing a Prolog predicate that takes arguments (A1, A2, L1, L2) and succeeds if all occurences of A1 within L1 have been changed to A2 in L2.
i.e.:
| ?- replace(a, b, [a], X).
X = [b]
Here's what I've written:
replace(Orig,_,[Other],[Other]) :- Other \== Orig.
replace(Orig,Repl,[Orig],[Repl]).
replace(Orig,Repl,[Other|T1],[Other|T2]) :- Other \== Orig, replace(Orig,Repl,T1,T2).
replace(Orig,Repl,[Orig|T1],[Repl|T2]) :- replace(Orig,Repl,T1,T2).
Now, this works, but seems a bit unelegant. Can there be a more elegant solution?
Thanks.
Solução 2
What about:
replace(A, B, X, Y) :- ( X == A -> Y = B ; Y = X ).
Example:
?- maplist(replace(1,x), [1,2,3], Ls).
Ls = [x, 2, 3].
It is easy to unfold the maplist/3
call into a recursive predicate if you prefer that.
Outras dicas
SICStus Prolog features dif/2
so you can define the relation in a pure manner like so:
replacement(A, B, X, Y) :-
( A = X, B = Y
; dif(A,X), X = Y
).
maplist_replacement([], [], _, _).
maplist_replacement([X|Xs], [Y|Ys], A, B) :-
replacement(A, B, X, Y),
maplist_replacement(Xs, Ys, A, B).
| ?- maplist_replacement([1,2,3],Ys, 1,x). Ys = [x,2,3] ? ; no | ?- maplist_replacement([X,Y],[X,Y],A,B). B = A, X = A, Y = A ? ; B = A, X = A, prolog:dif__int(A,Y) ? ; B = A, Y = A, prolog:dif__int(A,X) ? ; prolog:dif__int(A,X), prolog:dif__int(A,Y) ? ; no
The last query corresponds to the question: What must A
and B
look like such that a two element list will remain the same? There are four answers:
A
, B
, X
, and Y
are all the same.
A
, B
, and X
are the same, and Y
is different.
A
, B
, and Y
are the same, and X
is different.
X
and Y
are both different to A
.
In newer versions of SICStus, maplist/3
is in a library, however the definition is not entirely monotonic.
For a definition of maplist/3
see Prolog map procedure that applies predicate to list elements.