Sorting predicates in PROLOG

I don’t really like the findall/setof/… solutions for two reasons. First of all, if something unexpectedly fails you typically loose part of the answer without any feedback and second because it involves copying. Copying ground terms is fine (just costs memory and time), but for non-ground terms it already gets harder and for terms with constraints it quickly leads to incorrect results. I’d use this instead:

group_by_arg3(Terms, Grouped) :-
    map_list_to_pairs(arg(3), Terms, Keyed),
    keysort(Keyed, Sorted),
    group_pairs_by_key(Sorted, KeyGrouped),
    pairs_values(KeyGrouped, Grouped).

See SWISH -- SWI-Prolog for SHaring

That is the solution using library predicates. Alternatively, use sort/4 to sort the list on the 3th argument and do the splitting by hand. That is faster, but requires more writing.

At a more general level, Prolog programs handling this type of data as lists and doing such operations on them smells dubious. It could be fine. It could also be you are not using Prolog as a logic programming language but merely as an imperative data processing language. Prolog can do that, but the advantage compared to modern imperative languages is small. To judge though, one needs a much more complete picture about the problem you are trying to solve.

2 Likes