Search code examples
prolog

How do i remove reverse dulpicate list from a list in prolog?


I'm new to learn the prolog, I want to fulfill the predicate below.


removereverse([[1,5],[5,1],[2,3],[3,2]],List).  ---> Input

what I want:

List = [[1,5],[2,3]].

mycode


removes([],[]).
removes([[N1,N2]|T],[[N1,N2]|New]):-
    \+member([N1,N2],New),
    removes(T,New).


Solution

  • Something like this?

    First, lets define a predicate to tell us if a list is duplicated within a list-of-lists. This counts a list as a duplicate if either it or its reverse exists in the target list-of-lists:

    duplicated(X,Ls) :-               member(X,Ls).
    duplicated(X,Ls) :- reverse(X,R), member(R,Ls).
    

    Then we can say:

    clean( []     ,    []  ) .
    clean( [X|Xs] ,    Ys  ) :- duplicated(X,Xs), !, clean(Xs,Ys) .
    clean( [X|Xs] , [X|Ys] ) :-                      clean(Xs,Ys) .
    

    That keeps the last "duplicate" found and discard those preceding them in the source list. To keep the first such "duplicate" instead, just change where the recursion occurs:

    clean( []     ,    []  ) .
    clean( [X|Xs] ,    Ys  ) :- clean(Xs,Ys), duplicated(X,Xs), !.
    clean( [X|Xs] , [X|Ys] ) :- clean(Xs,Ys).
    

    Another approach uses a helper predicate:

    This keeps the first:

    clean( Xs, Ys ) :- clean(Xs,[],Y0), reverse(Y0,Ys).
    
    clean( []     , Ys, Ys ) .
    clean( [X|Xs] , Ts, Ys ) :- duplicated(X,Ts), !, clean(Xs,   Ts ,Ys).
    clean( [X|Xs] , Ts, Ys ) :-                      clean(Xs,[X|Ts],Ys). 
    

    To keep the last, simply change duplicate(X,Ts) to duplicate(X,Xs). The former checks to see if X exists in the accumulator Ts; the latter checks to see if X exists in the tail of the source list (Xs).