Richard
Richard

Reputation: 1117

Add non repeating elements to List in Prolog

I have a List and I am trying to add to it elements from another list that are not already present in the first List.

So if I had 2 Lists :

[a, b, 3, c] 
[2, a, b, 4]

The output would be:

[a, b, 3, c, 2, 4]

I am able to get it in reversed order but not in the correct one, here is what I am trying to do:

add_to_list(L, [], L).
add_to_list(List, [H|T], [H|Res]) :-
    \+ member(H, List),
    add_to_list(List, T, Res).
add_to_list(List, [H|T], Res):-
    add_to_list(List, T, Res).

And when I do the method with the 2 Lists mentioned above the output I get is:

[2, 4, a, b, 3, c]

I am aware that my ending clause is adding the L to the end of the result I get, which is why the order is a mess but how can I do it the correct way?

Upvotes: 0

Views: 101

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477824

Well the problem here is that you should first move to the end of the first list before concatenating data.

We can still use the code you have written, but alter it slightly like:

atl(_, [], []).
atl(List, [H|T], R) :-
    (  member(H, List)
    -> R = Res
    ;  R = [H|Res]
    ),
    atl(List, T, Res).

We here basically made three changes: (a) we renamed addToList/3 to atl/3; we changed L to [] in the first line; and (c) we used an if-then-else to prevent that the third clause gets triggered even if H is not a member of List (this was a semantical error in your code).

Now we will obtain for the given input as output:

?- atl([a, b, 3, c] , [2, a, b, 4], R).
R = [2, 4] ;
false.

So now we can write an addToList/3 in terms of atl/3: we first generate the list of items to append, and next we use append/3 to append these at the end of the list:

addToList(A, B, L) :-
    atl(A, B, R),
    append(A, R, L).

Upvotes: 1

Related Questions