In another post Jan W. noted
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).
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.
findall/setof/…is the complete list the predicates listed at Finding all Solutions to a Goal?
If something unexpectedly fails you typically loose part of the answer without any feedback.
I have no problem with that statement but noting it as a matter of fact so that others don’t think it is not important because I did not have it listed, it is important. (Others should ask questions if needed.)
Copying ground terms is fine (just costs memory and time)
Is there a way to identify if a copy is happening with a predicate?
I am thinking of something similar to the problem of knowing if a predicate leaves a choice point and how to find the predicate leaving the choice point, e.g.
a. To check if a predicate is deterministic (leaves no choice point) there is det/1
b. To see the predicate leaving the choice point
1. When at a top level prompt use
2. When debugging use gtrace/0 (ref)
The impetus for these questions is that many programmers are familiar with SQL and for this case specifically the SQL select statement. When learning to select and refine data many programmers will naturally try to leverage their knowledge of SQL in learning/using data selection and refinement with Prolog and thus the use of findall/setof…, sort/2, Aggregation operators on backtrackable predicates, etc. However as you note, Prolog is different especially when terms are not ground.
For those seeking a more inclusive list of Prolog items related to SQL see this.
For the longest time I had to guess at which predicates to use when printing and then you noted
A best practices is needed for
- Data selection.
- Data refinement.