0
votes

How do I implement in Prolog the predicate list_for_set(Xs, Cs) where Cs is a list that contains the same elements as Xs, in the order of its first occurrence, but whose number of occurrences is only 1. For example, the query

? - list_for_set([1, a, 3.3, a, 1.4], Cs).

it happens only for Cs = [1, a, 3,4]. The consultation

? - list_for_set ([1, a, 3,3, a, 1,4], [a, 1,3,4])

must fail.

The Cs list of the previous statement will be called a set list, that is, a list with only one occurrence of each element.

1
Come on, OP, this isn't so hard.David Tonhofer

1 Answers

0
votes

Ok, there is some trickery involved.

foofilter([],_,_-T) :- T=[]. % close difflist

foofilter([L|Ls],Seen,H-T) :-
   member(L,Seen),
   !,
   foofilter(Ls,Seen,H-T).

foofilter([L|Ls],Seen,H-T) :-
   \+member(L,Seen),
   !,
   T=[L|NewT],
   foofilter(Ls,[L|Seen],H-NewT).
:-begin_tests(filter).

data([1, a, 3, 3, a, 1, 4]).

test(one) :- data(L),
             DiffList=[[]|T]-T,  % Assume [] is never in L
             foofilter(L,[],DiffList),
             DiffList=[_|Result]-_,
             format("~q ==> ~q\n",[L,Result]),
             Result = [1,a,3,4].

:-end_tests(filter).

rt :- run_tests(filter).

Run tests:

?- rt.
% PL-Unit: filter [1,a,3,3,a,1,4] ==> [1,a,3,4]
. done
% test passed
true.

Someone will probably come up with a one-liner.