# Module aggregate

The aggregate predicates take a set of solutions and compute an aggregate on it. The predicate accumulate/3 aggregates the solution that is produced by findall/3. The predicate aggregate/3 respectively sys_collect/3 aggregates the solutions that are produced by bagof/3 respectively sys_heapof/3. The current implementation is not yet optimal, since the solution lists are always materialized.

Examples:
`?- [user].p(4,5).p(1,2).p(1,3).Yes?- aggregate((sum(X),count),p(Y,X),R).Y = 4,R = (5,1) ;Y = 1,R = (5,2)`

The following aggregate predicates are provided:

accumulate(A, G, R):
The predicate finds all the solutions to the goal G. It then computes the aggregate A from the solutions. The predicate then succeeds when R unifies with the result. The following aggregates are recognized:
count: The result is the number of solutions.
sum(X): The result is the sum of the X values.
min(X): The result is the minimum of the X values.
max(X): The result is the maximum of the X values.
bag(X): The result is the list of the X values.
nodup(X): The result is the list of the distinct X values.
set(X): The result is the list of the sorted X values.
(A,B): The result is the pairing of the aggregate A and B.
aggregate(A, X1^…^Xn^G, R):
The predicate determines all the solutions to the goal G, whereby computing the aggregate A of the solutions grouped by the witnesses. The predicate then repeatly succeeds by unifying the witnesses and when R unifies with the result.
sys_collect(S, X1^…^Xn^G, R):
The predicate determines the same results as the predicate aggregate/3. But the results are sorted by the witnesses instead of grouped by the witnesses.
foreach(G, H):
Calls the conjunction of those instances of H where G succeeds. Variables occuring in H and not occuring in G are shared across the conjunction.