2

Suppose I have a list of lists

L= [[1,2,3], [3,2,1],[2,1,2],[3,1,2], [1,2,2]].

as you can see, [1,2,3],[3,2,1] and [3,1,2] are permutations of each other. [2,1,2] and [1,2,2] are also permutations of each other.

My goal is to remove all permutations of elements in the list. the result list should be:

L'=[[1,2,3],[2,1,2]].

My idea so far is use member(X,L) to locate an element in the list, then use permutation(X,Xperm) to get a permutation of X, then check if Xperm is in L , and if so ,delete it.

However the result turns out not to be what I wanted.

Could anyone help me?

2 Answers2

0

Last time I did anything with Prolog was over 20 years ago, so I don't remember anything Prolog specific.

However, if I were to do this in any functional-friendly language, I would sort all the sublists in the big list, and then remove all the duplicates.

zmbq
  • 38,013
  • 14
  • 101
  • 171
0

One way to eliminate the duplicates is to use the standard recursive process for removing duplicates, but rather than checking equality directly through unification, change the code to try unifying sorted lists.

/* This is the regular duplicate elimination
   that sorts the head element before checking for duplicates
*/
remove_dups([],[]).
remove_dups([H|T], TT) :- msort(H,SH), contains_dup(SH,T), remove_dups(T, TT).
remove_dups([H|T], [H|TT]) :- msort(H,SH), \+ contains_dup(SH,T), remove_dups(T, TT).

/* This duplicate checker routine sorts the lists before trying to unify them */
contains_dup(_, []) :- fail.
contains_dup(SH, [H|_]) :- msort(H, SH).
contains_dup(SH, [_|T]) :- contains_dup(SH, T).

The code uses SWI's msort/2 predicate.

Here is a demo on ideone.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • If L=[[0,0,1],[0,1,1]], remove_dups gave me X = [[0, 1, 1]]. which is not right. Is it because SWI-prolog's sort will remove duplicates? eg in my prolog implementation,sort([0,0,1])=[0,1]. – user2683732 Nov 02 '13 at 20:58
  • @user2683732 You're right, I missed that part. `sort/2` does remove duplicates. Switch to `msort/2` to avoid that behavior. – Sergey Kalinichenko Nov 02 '13 at 21:17