## Beware of the empty solution

"The aggregate/3 version performs bagof/3 on Goal." means that the call will **fail** when there are no solutions. This is exactly right when working in "logical mode" where you search for an acceptable solution and fail if there is none. As opposed to "computational/traditional mode" where you are ok with an empty solution set and then decide to throw, issue an error message or explicity try something else. (Prolog code is actually an interleaving of those two thinking modes, one driven by logic&search, the other by computation&interaction, but this is never made really explicit anywhere)

Take this logic program:

fact(a,a). fact(a,b). fact(a,c).

Then

?- aggregate(count, X^fact(a,X), Count). Count = 3.

But instead of `Count==0`

, you get a failure if there are no solutions:

?- aggregate(count, X^fact(c,X), Count). false.

To "switch to computational mode" use the if-then-else operator ->/2.

?- (aggregate(count, X^fact(c,X), Count) -> true ; Count=0). Count = 0.

Or use aggregate_all/3, which is based on findall/3, which works in "computational mode" (its solution is the empty list if there are no solutions). That predicate doesn't use the caret notation because findall/3 doesn't use the caret notation:

?- aggregate_all(count, fact(c,X), Count). Count = 0. ?- aggregate_all(count, fact(a,X), Count). Count = 3.

## Example with a dict

Suppose you have an SWI-Prolog dict with integer values and you want to sum over those values:

dict_sum(_{} ,0) :- !. dict_sum(Dict,Total) :- aggregate(sum(Val), Key^get_dict(Key,Dict,Val), Total). :- begin_tests(sum). test(sum1, [ true(Total == 0) ]) :- dict_sum(_{},Total). test(sum2, [ true(Total == 3) ]) :- dict_sum(_{x:1,y:2},Total). :- end_tests(sum).