Как заказать список кортежей в Swi-Prolog - PullRequest
0 голосов
/ 05 мая 2018

У меня есть список в swi-прологе, как это:

[(5,4), (1,4), (3,12), (4,2), (5,4)]

Мне нужно, чтобы список был организован по второму элементу каждого «кортежа», удаляя все повторяющиеся элементы, чтобы этот список выглядел так:

[(4,2), (1,4), (5,4), (3,12)]

Используя предикат sort / 2, он делает все, что я хочу, за исключением того, что он организуется по первому элементу каждого кортежа, который я не хочу.

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Если вы не хотите писать собственную процедуру сортировки (сортировка вашего Пролога, вероятно, более оптимизирована, чем ваша), то могут существовать предикаты, специфичные для реализации, которые вы можете использовать при сравнении по вашему выбору.

Например, SWI-Prolog имеет predsort/3, который принимает предикат для сортировки. Вы можете использовать его с предикатом, который сравнивает первый элемент пары первым:

compare_by_second(<, (A, B), (C, D)) :-
    (   B @< D
    ;   B == D,
        A @< C ).
compare_by_second(=, (A, B), (C, D)) :-
    A == C,
    B == D.
compare_by_second(>, (A, B), (C, D)) :-
    (   B @> D
    ;   B == D,
        A @> C ).

% ?- predsort(compare_by_second, [(5,4), (1,4), (3,12), (4,2), (5,4)], Sorted).
%@ Sorted = [ (4, 2), (1, 4), (5, 4), (3, 12)] ;
%@ false.
0 голосов
/ 05 мая 2018

Вдохновленный http://kti.mff.cuni.cz/~bartak/prolog/sorting.html, Я изменил алгоритм сводки в соответствии с вашими потребностями. Я тестировал Sicstus Prolog, и он работал.

:- use_module(library(lists)).

pivoting(_,[],[],[]).
pivoting((A,B),[(C,D)|T],[(C,D)|L],G):-D>B,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],[(C,D)|L],G):-D=B,C>A,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,[(C,D)|G]):-D<B,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,[(C,D)|G]):-D=B,C<A,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,G):-A=C,D=B,pivoting((A,B),T,L,G).

quick_sort(List,Sorted):-q_sort(List,[],Sorted).
q_sort([],Acc,Acc).
q_sort([H|T],Acc,Sorted):-
    pivoting(H,T,L1,L2),
    q_sort(L1,Acc,Sorted1),q_sort(L2,[H|Sorted1],Sorted).
...