Did you know ... Search Documentation:
aggregate.pl -- SICStus 4 library(aggregate).
PublicShow source
See also
- https://sicstus.sics.se/sicstus/docs/4.6.0/html/sicstus/lib_002daggregate.html
Source term_variables(+Term, +Vars0, -Vars) is det
Vars is the union of Vars0 and all variables that occur in Term. This is not the same as SWI-Prolog's built-in term_variables/3 - the argument order is different and this predicate is guaranteed to return a list without duplicates.

Re-exported predicates

The following predicates are exported from this file while their implementation is defined in imported modules or non-module files loaded by this module.

Source aggregate(+Template, :Goal, -Result) is nondet
Aggregate bindings in Goal according to Template. The aggregate/3 version performs bagof/3 on Goal.
Source aggregate(+Template, +Discriminator, :Goal, -Result) is nondet
Aggregate bindings in Goal according to Template. The aggregate/4 version performs setof/3 on Goal.
Source aggregate_all(+Template, :Goal, -Result) is semidet
Aggregate bindings in Goal according to Template. The aggregate_all/3 version performs findall/3 on Goal. Note that this predicate fails if Template contains one or more of min(X), max(X), min(X,Witness) or max(X,Witness) and Goal has no solutions, i.e., the minimum and maximum of an empty set is undefined.

The Template values count, sum(X), max(X), min(X), max(X,W) and min(X,W) are processed incrementally rather than using findall/3 and run in constant memory.

Source aggregate_all(+Template, +Discriminator, :Goal, -Result) is semidet
Aggregate bindings in Goal according to Template. The aggregate_all/4 version performs findall/3 followed by sort/2 on Goal. See aggregate_all/3 to understand why this predicate can fail.
Source foreach(:Generator, :Goal)
True when the conjunction of instances of Goal created from solutions for Generator is true. Except for term copying, this could be implemented as below.
foreach(Generator, Goal) :-
    findall(Goal, Generator, Goals),
    maplist(call, Goals).

The actual implementation uses findall/3 on a template created from the variables shared between Generator and Goal. Subsequently, it uses every instance of this template to instantiate Goal, call Goal and undo only the instantiation of the template and not other instantiations created by running Goal. Here is an example:

?- foreach(between(1,4,X), dif(X,Y)), Y = 5.
Y = 5.
?- foreach(between(1,4,X), dif(X,Y)), Y = 3.

The predicate foreach/2 is mostly used if Goal performs backtrackable destructive assignment on terms. Attributed variables (underlying constraints) are an example. Another example of a backtrackable data structure is in library(hashtable). If we care only about the side effects (I/O, dynamic database, etc.) or the truth value of Goal, forall/2 is a faster and simpler alternative. If Goal instantiates its arguments it is will often fail as the argument cannot be instantiated to multiple values. It is possible to incrementally grow an argument:

?- foreach(between(1,4,X), member(X, L)).
L = [1,2,3,4|_].

Note that SWI-Prolog up to version 8.3.4 created copies of Goal using copy_term/2 for each iteration, this makes the current implementation unable to properly handle compound terms (in Goal's arguments) that share variables with the Generator. As a workaround you can define a goal that does not use compound terms, like in this example:

mem(E,L) :-  % mem/2 hides the compound argument from foreach/2

?- foreach(  between(1,5,N), mem(N,L)).
Source free_variables(:Generator, +Template, +VarList0, -VarList) is det
Find free variables in bagof/setof template. In order to handle variables properly, we have to find all the universally quantified variables in the Generator. All variables as yet unbound are universally quantified, unless
  1. they occur in the template
  2. they are bound by X^P, setof/3, or bagof/3

free_variables(Generator, Template, OldList, NewList) finds this set using OldList as an accumulator.

- Richard O'Keefe
- Jan Wielemaker (made some SWI-Prolog enhancements)
- Public domain (from DEC10 library).
To be done
- Distinguish between control-structures and data terms.
- Exploit our built-in term_variables/2 at some places?

Undocumented predicates

The following predicates are exported, but not or incorrectly documented.

Source forall(Arg1, Arg2)