Sorting predicates in PROLOG

Implemented as:

test_sort_group(Group) :-
    Patients = [patient(204,4,2),patient(203,3,2),patient(304,8,3),patient(303,7,3),patient(404,12,4),patient(403,11,4),patient(504,16,5),patient(503,15,5),patient(1,1,1),patient(506,6,5)],
    group_list_by_arg(3, Patients, Group).


group_list_by_arg(Arg, Lst, Group) :-
    % Keeping duplicates
    sort(Arg, @=<, Lst, [H|T]),
    group_list_by_arg_main_(T, Arg, H, Group).

group_list_by_arg_main_(T, Arg, H, Group) :-
    arg(Arg, H, ArgVal),
    Upto = [H|Upto0],
    group_list_by_arg_loop_(T, Arg, ArgVal, Upto0, Rem),
    group_list_by_arg_rem_(Rem, Arg, Upto, Group).

% Reached end of groups
group_list_by_arg_rem_([], _, G, G).
group_list_by_arg_rem_([_|_], _, G, G).
group_list_by_arg_rem_([H|T], Arg, _Upto, Group) :-
    % Assemble next group
    group_list_by_arg_main_(T, Arg, H, Group).

% Reached end of sorted list
group_list_by_arg_loop_([], _, _, [], []).
group_list_by_arg_loop_([H|T], Arg, ArgVal, Group, Rem) :-
    arg(Arg, H, ArgVal), !,
    % Add element to current group
    Group = [H|Group0],
    group_list_by_arg_loop_(T, Arg, ArgVal, Group0, Rem).
% Finished this group, but there may be other elements
group_list_by_arg_loop_([H|T], _Arg, _ArgVal, [], [H|T]).
?- time(bagof(G, test_sort_group(G), Gs)).
% 49 inferences, 0.000 CPU in 0.000 seconds (94% CPU, 599807 Lips)
Gs = [[patient(1,1,1)],[patient(204,4,2),patient(203,3,2)],[patient(304,8,3),patient(303,7,3)],[patient(404,12,4),patient(403,11,4)],[patient(504,16,5),patient(503,15,5),patient(506,6,5)]].
1 Like