I'm attempting to find the complement of a list, given a list L1, and a universal list L2 with the following code:
complement(L1, L2, Res):-
setof(X, (nth0(N, L2, X), not(member(X,L1))),Res).
However, my results include duplicates and are not given in list form as I'd prefer:
23 ?- complement([1,3], [-1,1,3,5,2,4,2,55,1,0], Res).
Res = [-1] ;
Res = [5] ;
Res = [2] ;
Res = [4] ;
Res = [2] ;
Res = [55] ;
Res = [0].
I figured it's probably due to Prolog's built-in backtracking but I'm not sure how to work around this to go about formatting the result correctly and getting it to remove any duplicate items in the result.
You get a warning from your code, about N
being a singleton, and setof/3 requires that each variable 'universally quantified' get declared.
So, you have two problems that go away together: replace nth0/3 by member/2:
complement(L1, L2, Res):-
setof(X, (member(X, L2), not(member(X, L1))), Res).
edit
symmetric difference could be
symdiff(L1,L2,Diff) :-
setof(X,(eldiff(L1,L2,X);eldiff(L2,L1,X)),Diff).
eldiff(L1,L2,X) :-
member(X,L1), \+member(X,L2).
if L1 and L2 are ordered sets, much better to use ord_symdiff