I need to make a sum of two lists which has no repeated elements inside the result (i.e a union). For example:
?- union([3,4,c,5], [7,f,c,3], X).
X = [3, 4, c, 5, 7, f].
The basic idea seems to be to get each element of List A and add them onto the output while doing so.
After list A is empty, go over list B and only add those elements that were also not in list A.
What I have thus far is this:
union([],[],[]).
union(List1,[],List1).
union([Head1|Tail1],List2,[Head1|Output]):-
union(Head1,List2,Output).
This predicate will
result in an empty list upon calling it using empty lists,
result in List1 upon calling it with an empty List2 and
Use list recursion to pass all the List1 elements onto the Output.
The issue I'm having is with checking whether or not the elements of List2 are in also in List1.
My attempt:
union(List1, [Head2|Tail2], [Head2|Output]):-
not(member(Head2,List1)), union(List1,Tail2,Output).
union(List1, [Head2|Tail2], Output):-
member(Head2,List1), union(List1,Tail2,Output).
This did not result in the correct answer. I assume it is because when the program reaches
not(member(Head2,List1))
at this point List1 would be empty as a result of
union([Head1|Tail1],List2,[Head1|Output]):-
union(Head1,List2,Output).
which would mean all elements of List2 get appended onto the Output.
How exactly would I be able to make the check that an element of List2 is not in List1 if List1 is empty by the time I get to checking? Or is there another solution to this whole problem?
\+/1
, rather thannot/1
– Daniel Lyonsunion(X, Y, Z) :- setof(E, (member(E, X); member(E, Y)), Z).
because if you read it out loud it sounds just like your problem. – Daniel Lyonsunion([],[],[])
intended? – false