Prolog 从列表的所有重复元素中选择最小值

Prolog 从列表的所有重复元素中选择最小值,prolog,Prolog,举个例子可以更好地解释我想做的事情。 例如,我有一个序言列表: L=[(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)] 我想生成以下列表: L'=[(d,15),(g,23),(e,14),(h,23)] 也就是说,从元素(X,u)的所有出现中,保留Y最小的元素。不是很优雅,而是。。。下面的代码呢 getFirst((X, _), X). isMinor(_, []). isMinor((X1, Y1), [(X2, _) | T]) :- X1

举个例子可以更好地解释我想做的事情。 例如,我有一个序言列表:

L=[(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)]
我想生成以下列表:

L'=[(d,15),(g,23),(e,14),(h,23)]

也就是说,从元素(X,u)的所有出现中,保留Y最小的元素。

不是很优雅,而是。。。下面的代码呢

getFirst((X, _), X).

isMinor(_, []).

isMinor((X1, Y1), [(X2, _) | T]) :-
  X1 \= X2,
  isMinor((X1, Y1), T).

isMinor((X, Y1), [(X, Y2) | T]) :-
  Y1 =< Y2,
  isMinor((X, Y1), T).

purgeList(_, [], []).

purgeList(X1, [(X2, Y2) | Tin], [(X2, Y2) | Tout]) :-
  X1 \= X2,
  purgeList(X1, Tin, Tout).

purgeList(X, [(X, _) | Tin], Tout) :-
  purgeList(X, Tin, Tout).

filterList([], []).

filterList([H1 | Tin1], [H1 | Tout]) :-
  isMinor(H1, Tin1),
  getFirst(H1, X),
  purgeList(X, Tin1, Tin2),
  filterList(Tin2, Tout).

filterList([H1 | Tin], Tout) :-
  \+ isMinor(H1, Tin),
  filterList(Tin, Tout).
我获得(
L
与统一)

你也可以写:

select_elements(L,Lout):-        
  sort(L,L1),
  reverse(L1,L2),
  remove(L2,L3),
  output_list(L,L3,Lout).

remove([],[]).
remove([H],[H]).
remove([(X,Y1),(X,Y2)|T],[(X,Y1)|T1]):-remove([(X,Y2)|T],T1).
remove([(X1,Y1),(X2,Y2)|T],[(X1,Y1)|T1]):-
       dif(X1,X2),\+member((X2,_),T),
       remove([(X2,Y2)|T],T1).
remove([(X1,Y1),(X2,_)|T],[(X1,Y1)|T1]):-
       dif(X1,X2),member((X2,_),T),
       remove(T,T1).


output_list([],_,[]).
output_list([H|T],L,[H|T1]):-member(H,L),output_list(T,L,T1).
output_list([H|T],L,T1):- \+member(H,L),output_list(T,L,T1).
例如:

?- select_elements([(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)],L).
L = [ (d, 15), (g, 23), (e, 14), (h, 23)] ;
false.
你可以试试

test((V, N), Y, Z) :-
    (  member((V,N1), Y)
    -> (  N < N1
       -> select((V,N1), Y, (V,N), Z)
       ;  Z = Y)
    ;   append(Y, [(V,N)], Z)).

my_select(In, Out) :-
    foldl(test, In, [], Out).

不是很优雅,但这正是我想要的,而且很有效。谢谢
?- select_elements([(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)],L).
L = [ (d, 15), (g, 23), (e, 14), (h, 23)] ;
false.
test((V, N), Y, Z) :-
    (  member((V,N1), Y)
    -> (  N < N1
       -> select((V,N1), Y, (V,N), Z)
       ;  Z = Y)
    ;   append(Y, [(V,N)], Z)).

my_select(In, Out) :-
    foldl(test, In, [], Out).
 ?- my_select([(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)], Out).
Out = [(d,15),(e,14),(g,23),(h,23)] ;
false.