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