4.13.2 Collecting a Sorted List

setof(Template, Generator, Set) returns the set Set of all instances of Template such that Generator is provable, where that set is non-empty. The term Generator specifies a goal to be called as if by call/1. Set is a set of terms represented as a list of those terms, without duplicates, in the standard order for terms (see ref-lte-cte).

Obviously, the set to be enumerated should be finite, and should be enumerable by Prolog in finite time. It is possible for the provable instances to contain variables, but in this case Set will only provide an imperfect representation of what is in reality an infinite set.

If Generator is instantiated, but contains uninstantiated variables that don't also appear in Template, setof/3 can succeed nondeterminately, generating alternative values for Set corresponding to different instantiations of the free variables of Generator. (It is to allow for such usage that Set is constrained to be non-empty.) For example, if your program contained the clauses

     likes(tom, beer).
     likes(dick, beer).
     likes(harry, beer).
     likes(bill, cider).
     likes(jan, cider).
     likes(tom, cider).

the call

     | ?- setof(X, likes(X,Y), S).

might produce two alternative solutions via backtracking:

     X = _872,
     Y = beer,
     S = [dick,harry,tom] ;
     X = _872,
     Y = cider,
     S = [bill,jan,tom] ;

The call

     | ?- setof((Y,S), setof(X,likes(X,Y),S), SS).

would then produce

     Y = _402,
     S = _417,
     X = _440,
     SS = [(beer,[dick,harry,tom]),(cider,[bill,jan,tom])] ;

See mpg-ref-setof.

Send feedback on this subject.