B-Prolog provides a built-in, called foreach, and the list comprehension notation for writing repetition. The foreach built-in has a very simple syntax and semantics. For example, foreach(A in [a,b], I in 1..2, write((A,I))) outputs four tuples: (a,1), (a,2), (b,1), and (b,2). Syntactically, foreach is a variable-length call whose last argument specifies a goal that should be executed for each combination of values in a sequence of collections. A foreach call may also give a list of variables that are local to each iteration, and a list of accumulators that can be used to accumulate values from each iteration. With accumulators, users can use foreach in order to describe recurrences for computing aggregates. Recurrences have to be read procedurally, and thus do not fit well with Prolog. For this reason, B-Prolog borrows list comprehensions from functional languages. A list comprehension is a list whose first element has the functor ':'/2
. A list of this form is interpreted as a list comprehension in calls to '@='/2
, and in some other contexts. For example, the query X@=[(A,I) : A in [a,b], I in 1..2]
binds X to the list [(a,1),(a,2),(b,1),(b,2)]
. A list comprehension is treated as a foreach call with an accumulator in the implementation.