Prolog - How can I return a list where each element appears only once?

Viewed 133

I have a predicate set/2 that is supposed to instantiate the second argument to a list whose elements are only one occurance of each term from the first argument. What I have so far is:

set([],OutList).
set([X|InList],OutList) :- \+member(X,InList), append([X], OutList, OutListNew), set(InList,OutListNew).                      
set([X|InList],OutList) :- member(X,InList), set(InList,OutList).

And calling set/2:

set([1,1,2,3],X).

returns true. That's halfway there - I want X to be instantiated to [1,2,3] - but I'm not sure how to make X true in this case. Any help and explanations would be appreciated.

2 Answers

Your Prolog should warn you have a singleton in the first clause, that is

set([],OutList).

It means that when the execution hits such clause, it succeeds, but OutList remains unbound.

Now should be clear that you need to substitute OutList with the empty list.

Another bug is located in the second clause.

append([X], OutList, OutListNew) should be instead append([X], OutListNew, OutList). As a style note, it can be substituted by this unification: [X|OutListNew]=OutList, and then moved into the head.

Related