[comp.lang.prolog] aggregates

philip@mulga.oz (Philip Dart) (10/13/87)

Richard O'Keefe writes about aggregate/3 in Quintus prolog ...

>    It is very easy to build such a predicate on top of setof/3,
>    and for operations like finding the average, minimum, or maximum,
>    refusing to yield an empty list is just what the doctor ordered.
>    It would be interesting to discuss what the aggregate/3 operation
>    should look like:  the present version is satisfactory but there
>    is more that it could do.

As well as solutions/3, setof/3, bagof/3 and findall/3, NU-Prolog provides
four aggregate functions: count/3, max/3, min/3 and sum/4

Arguments to these predicates fall into the following categories.

Goal:   This acts as a generator, producing solutions of the form Term.

Term:	The aggregate is concerned only with distinct instantiations of Term.

Subterm:   What the aggregate operation, eg. + or >, is applied to.

Result:   What the result of the aggregate is unified with.

count/3 is concerned only with `how many' of something there is; it can
therefore make use of just three of these arguments:

	count(Term, Goal, Result)

	eg. count(Term, member(Term, [pear, apple, orange, pear]), 3).

max/3 (and similarly min/3) needs to apply a comparison operation to
some term, but repeated occurrences of any term will not change the result:

	max(Subterm, Goal, Result)

	eg. max(Subterm, member(Subterm, [1, 2, 3, 4, 2, 2, 1]), 4).

sum/4 requires all four arguments: Consider trying to find the sum of the
salaries of all employees in 'sales' or 'service'. If some employee
is in both departments, we still only want to include his salary once
(unless of course he is paid by both :-).

employs(sales, fred).		paidTo(fred, 10000).
employs(sales, bill).		paidTo(bill, 20000).
employs(service, harry).	paidTo(harry, 30000).
employs(service, bill).

sum(Salary, Emp-Salary,
	some Dept (
		(Dept = sales ; Dept = service),
		employs(Dept, Emp),
		paidTo(Emp, Salary)
		),
	60000).

(The use of 'some' simply indicates that the variable Dept is used only
in the Goal in the aggregate.)
In general, sum/4 has the form:

sum(Subterm, Term, Goal, Result)

but since Subterm (or at least all the variables in it) would always
have to be repeated in Term, sum/4 uses the combination of its first
two arguments in looking for unique solutions.
For this reason, in the above example, Emp-Salary should be replaced
by Emp.

A final example:

sum(S*3, T,
	member(T/S, [orange/10, pear/100, apple/1, apple/1, apple/1000]),
	3333).

count/3 can be defined trivially in terms of sum/4:

count(Term, Goal, Result) :- sum(1, Term, Goal, Result).

There are other issues relating to aggregates to be considered
such as whether solutions should be ground.