问题
My task is to make myReplace(E1,L1,E2,L2) such that the very first occurrence of E1 in L1 gets replaced by E2 and is returned in L2. I have written the below described code and it is working properly.
myReplace(E1,[],E2,[]).
myReplace(E1,[E1|Xs],E2,[E2|Ys]):-
myReplace(E1,Xs,E1,Ys).
myReplace(E1,[H|Hs],E2,[H|Ts]):-
E1 \= H,
myReplace(E1,Hs,E2,Ts).
However, For example myReplace(2,[1,2,3,2,1],5,X) should give X = [1,5,3,2,1] and X = [1,2,3,5,1]. But my code is only giving one solution which is X = [1,5,3,2,1].
Similarly, when myReplace(2,X,5,[1,5,3,5,1]) should backtrack over the solutions X = [1,2,3,5,1] and X = [1,5,3,2,1] only, but my solution gives me one more solution as X = [1,5,3,5,1].
Could you please help me resolve this.
Thank you :)
回答1:
What about
myReplace(E1,[E1|Xs],E2,[E2|Xs]).
myReplace(E1,[H|Hs],E2,[H|Ts]):-
myReplace(E1,Hs,E2,Ts).
?
If I'm not wrong, this impose one (and only one) replacement.
Take in count that you have to delete
myReplace(E1,[],E2,[]).
otherwise you get L1 = L2 (no replacement) as a solution.
And observe that, as pointed by Lurker, this isn't "the very first occurrence of E1 in L1 gets replaced".
回答2:
If I understand your question, you want to get all answers from substituting each one occurrence of E1 in L1. You can get the backtracking for free if you use append/3 for this:
my_replace(X, As, Y, Bs) :-
append(As_front, [X|As_back], As),
append(As_front, [Y|As_back], Bs).
With this definition I get:
?- my_replace(2,[1,2,3,2,1],5,X).
X = [1, 5, 3, 2, 1] ;
X = [1, 2, 3, 5, 1] ;
false
See the other solution to see how to see what the problem with your original code was.
来源:https://stackoverflow.com/questions/39645187/replacing-elements-between-two-lists-using-prolog