<< Prev | - Up - |

`setof/3`

The `setof/3`

predicate is basically the same as `bagof`

, but with one useful difference: the lists it contains are *ordered* and contain *no redundancies* (that is, each item appears in the list only once).

For example, suppose we have the following database

`age(harry,13).`

age(draco,14).

age(ron,13).

age(hermione,13).

age(dumbledore,60).

age(hagrid,30).

Now suppose we want a list of everyone whose age is recorded in the database. We can do this with the query:

`findall(X,age(X,Y),Out).`

X = _8443

Y = _8448

Out = [harry,draco,ron,hermione,dumbledore,hagrid]

But maybe we would like the list to be ordered. We can achieve this with the following query:

`setof(X,Y ^ age(X,Y),Out).`

(Note that, just like with`bagof`

, we have to tell `setof`

not to generate separate lists for each value of `Y`

, and again we do this with the `^`

symbol.)

This query yields:

`X = _8711 `

Y = _8715

Out = [draco,dumbledore,hagrid,harry,hermione,ron]

Note that the list is alphabetically ordered.

Now suppose we are interested in collecting together all the ages which are recorded in the database. Of course, we can do this with the following query:

`findall(Y,age(X,Y),Out).`

Y = _8847

X = _8851

Out = [13,14,13,13,60,30]

But this output is rather messy. It is unordered and contains repetitions. By using `setof`

we get the same information in a nicer form:

`setof(Y,X ^ age(X,Y),Out).`

Y = _8981

X = _8985

Out = [13,14,30,60]

Between them, these three predicates offer us a lot of flexibility. For many purposes, all we need is `findall`

. But if we need more, `bagof`

and `setof`

are there waiting to help us out.

<< Prev | - Up - |

Patrick Blackburn, Johan Bos and Kristina Striegnitz

Version 1.2.5 (20030212)