replacing elements between two lists using prolog

2019-09-07 04:48发布

问题:

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.



标签: list prolog