setof/3

Module: builtins

setof/3 — all unique solutions for a goal, sorted
bagof/3 — all solutions for a goal, not sorted
findall/3 — all solutions for a goal, not sorted
b_findall/4 — bound list of solutions for a goal, not sorted

ISO Standard Predicate

FORMS

setof(Template, Goal, Collection)

bagof(Template, Goal, Collection)

findall(Template, Goal, Collection)

b_findall(Template, Goal, Collection, Bound)

DESCRIPTION

These predicates collect in the list Collection, the set of all instances of Template such that the goal, Goal, is provable. Template is a term that usually shares variables with Goal.

setof/3 produces a Collection which is sorted according to the standard order with all duplicate elements removed. Both bagof/3 and findall/3 produce Collections that are not sorted.

If there are no solutions to Goal, then setof/3 and bagof/3 will fail, whereas, findall/3 unifies Collection with [].

Variables that occur in Goal and not within Template are known as free, variables. setof/3 and bagof/3 will generate alternative bindings for free variables upon backtracking.

Within a call to setof/3 or bagof/3, free variables can be existentially quantified in Goal by using the notation Variable^Query. This means that there exists a Variable such that Query is true.

The collection to be enumerated should be finite, and should be enumerable by Prolog in finite time. It is possible for the provable instances of Template to contain variables, but in this case Collection will only provide an imperfect representation of what is actually an infinite collection.

setof/3 calls upon sort/2 to eliminate duplicate solutions from Collection, which seriously impacts its efficiency. In addition, even though bagof/3 leaves duplicate solutions, it still calls keysort/2.

findall/3 neither removes duplicates nor generates alternative bindings for free variables; it assumes that all variables occurring within Goal are existentially quantified. As a result, findall/3 is much more efficient than either setof/3 or bagof/3.

When Bound is a positive integer, b_findall/4 operates similarly to findall/3, except that it returns at most Bound number of solutions on the list Collection. It fails if Bound is anything other than a positive integer.

EXAMPLES

?- listing.
% user:likes/2
likes(kev,running).
likes(kev,lifting).
likes(keith,running).
likes(keith,lifting).
likes(ken,swimming).
likes(sally,swimming).
likes(andy,bicycling).
likes(chris,lifting).
likes(chris,running).
yes.
?- setof(Person, likes(Person, Sport), SetOfPeople).
Person = _1
Sport = bicycling
SetOfPeople = [andy];
Person = _1
Sport = lifting
SetOfPeople = [chris,keith,kev];
Person = _1
Sport = running
SetOfPeople = [chris,keith,kev];
Person = _1
Sport = swimming
SetOfPeople = [sally,ken];
no.
?- setof((Sport,People),
setof(Person, likes(Person, Sport), People),
Set).
Sport = _1
People = _2
Person = _4
Set = [(bicycling,[andy]),(lifting,[chris,keith,kev]),
(running,[chris,keith,kev]),(swimming,[sally,ken])]
yes.
?- setof(Person, Sport^(likes(Person, Sport)), SetOfPeople).
Person = _1
Sport = _2
SetOfPeople = [andy,chris,sally,keith,ken,kev]
yes.

SEE ALSO