/usr/local/lib/swipl/library/aggregate.pl
All Application Manual Name SummaryHelp

  • swipl
    • library
      • error.pl
      • debug.pl
      • apply.pl -- Apply predicates on a list
      • lists.pl -- List Manipulation
      • broadcast.pl
      • shlib.pl -- Utility library for loading foreign objects (DLLs, shared objects)
      • option.pl -- Option list processing
      • thread_pool.pl -- Resource bounded thread management
      • gensym.pl -- Generate unique symbols
      • settings.pl
      • arithmetic.pl
      • main.pl -- Provide entry point for scripts
      • readutil.pl -- Read utilities
      • operators.pl
      • pairs.pl
      • prolog_source.pl
      • record.pl -- Access compound arguments by name
      • quasi_quotations.pl -- Define Quasi Quotation syntax
      • pure_input.pl
      • solution_sequences.pl -- Modify solution sequences
      • ordsets.pl -- Ordered set manipulation
      • random.pl -- Random numbers
      • base64.pl -- Base64 encoding and decoding
      • aggregate.pl -- Aggregation operators on backtrackable predicates
        • safe_meta/2
        • aggregate/3
        • aggregate/4
        • aggregate_all/3
        • aggregate_all/4
        • foldall/4
        • foreach/2
        • free_variables/4
      • yall.pl
      • sandbox.pl
      • apply_macros.pl -- Goal expansion rules to avoid meta-calling
      • assoc.pl -- Binary associations
      • prolog_format.pl -- Analyse format specifications
      • predicate_options.pl -- Access and analyse predicate options
      • csv.pl -- Process CSV (Comma-Separated Values) data
      • pprint.pl -- Pretty Print Prolog terms
      • atom.pl -- Operations on atoms
      • modules.pl
      • occurs.pl
      • prolog_xref.pl -- Prolog cross-referencer data collection
      • prolog_colour.pl -- Prolog syntax colouring support.
      • lazy_lists.pl
      • ugraphs.pl -- Graph manipulation library
      • url.pl
      • www_browser.pl
      • prolog_pack.pl -- A package manager for Prolog
      • git.pl -- Run GIT commands
      • utf8.pl
      • dialect.pl
      • system.pl -- System utilities
      • terms.pl -- Term manipulation
      • date.pl -- Process dates and times
      • persistency.pl
      • iostream.pl -- Utilities to deal with streams
      • prolog_stack.pl
      • edinburgh.pl -- Some traditional Edinburgh predicates
      • prolog_clause.pl
      • prolog_breakpoints.pl
      • wfs.pl -- Well Founded Semantics interface
      • prolog_code.pl -- Utilities for reasoning about code
      • sort.pl
      • dicts.pl
      • dif.pl
      • varnumbers.pl -- Utilities for numbered terms
      • pio.pl
      • prolog_profile.pl -- Execution profiler
      • base32.pl
      • charsio.pl -- I/O on Lists of Character Codes
      • codesio.pl
      • coinduction.pl
      • heaps.pl -- heaps/priority queues
      • rbtrees.pl
      • statistics.pl
      • when.pl -- Conditional coroutining
      • backcomp.pl
      • quintus.pl -- Quintus compatibility
      • tables.pl
      • nb_set.pl
      • threadutil.pl -- Interactive thread utilities
      • prolog_coverage.pl
      • optparse.pl
      • prolog_debug.pl -- User level debugging tools
      • prolog_trace.pl -- Print access to predicates
      • listing.pl -- List programs and pretty print clauses
      • thread.pl -- High level thread primitives
      • prolog_autoload.pl
      • check.pl -- Consistency checking
      • prolog_codewalk.pl -- Prolog code walker
      • ctypes.pl -- Character code classification
      • shell.pl -- Elementary shell commands
      • increval.pl
      • portray_text.pl
      • ansi_term.pl -- Print decorated text to ANSI consoles
      • strings.pl -- String utilities
      • intercept.pl -- Intercept and signal interface
      • help.pl
      • hashtable.pl -- Hash tables
      • edit.pl -- Editor interface
      • prolog_wrap.pl -- Wrapping predicates
      • zip.pl
      • files.pl
      • writef.pl
      • prolog_versions.pl -- Demand specific (Prolog) versions
      • make.pl -- Reload modified source files
      • prolog_config.pl
      • explain.pl
      • fastrw.pl
      • streams.pl -- Manage Prolog streams
 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.
false.

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
   member(r(E),L).

?- foreach(  between(1,5,N), mem(N,L)).