One summary per group

A non-aggregate head argument splits the rows into groups: one summary per distinct value.

For example, we can count how many variables are negated in each clause C in our CNF example:

count_neg(C, count(V)) :- literal(C, V, 0).

This works as follows:

  1. Evaluate the body of the predicate; result is a set of tuples (C, V).
  2. For each C, add a row (C, n) to count_neg where n is the number of tuples whose first component is C.
Flat fan-in diagram with rounded rectangular pill nodes and directed arrows on a white background. A left column, headed by the italic teal label 'negated literals', has three pills stacked vertically: 'clause 1: not-q' in teal (light-teal fill, teal border), then 'clause 2: not-q' and 'clause 2: not-r' both in amber (pale-amber fill, amber-brown border). A right column, headed by the italic teal label 'count per clause', has two larger pills: a teal 'clause 1 to 1' at top and an amber 'clause 2 to 2' below. Colour-coded arrows fan in from left to right: one teal arrow from the clause-1 pill to 'clause 1 to 1', and two amber arrows from the two clause-2 pills converging on 'clause 2 to 2'. Dark teal text throughout.