如何从序言列表中删除反向重复列表?

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

我刚开始学序言,我想完成下面的谓词。


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

what I want:

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

我的代码


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

是这样的吗?

首先,让我们定义一个谓词来告诉我们列表是否在 list-of-lists 中重复。如果列表或其反向存在于目标 list-of-lists:

中,则将列表视为重复项
duplicated(X,Ls) :-               member(X,Ls).
duplicated(X,Ls) :- reverse(X,R), member(R,Ls).

那么我们可以说:

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

这会保留找到的最后一个“重复项”,并丢弃源列表中位于它们之前的那些。要保留第一个这样的“重复”,只需更改递归发生的位置:

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

另一种方法使用辅助谓词:

这保留第一个:

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

要保留最后一个,只需将 duplicate(X,Ts) 更改为 duplicate(X,Xs)。前者检查累加器Ts中是否存在X;后者检查 X 是否存在于源列表的尾部 (Xs).