listprologlogicunification

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


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.


Solution

  • 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.