Examples

   ?-foreach(I in [1,2,3],format("~d ",I)).
   1 2 3

   ?-foreach(I in 1..3,format("~d ",I)).
   1 2 3

   ?-foreach(I in 3..-1.. 1,format("~d ",I)).
   3 2 1

   ?-foreach(F in 1.0..0.2..1.5,format("~1f ",F)).
   1.0 1.2 1.4
 
   |?-foreach(T in ([a,b],1..2),writeln(T))
   a,1
   b,2

   |?-foreach((A,N) in ([a,b],1..2),writeln(A=N)
   a=1
   b=2

   ?-foreach(L in [[1,2],[3,4]], (foreach(I in L, write(I)),nl)).
   12
   34

   ?-functor(A,t,10),foreach(I in 1..10,arg(I,A,I)).
   A = t(1,2,3,4,5,6,7,8,9,10)

   ?-foreach((A,I) in [(a,1),(b,2)],writeln(A=I)).
   a=1
   b=2

The power of foreach is more clearly revealed when it is used with arrays. The following predicate creates an N x N array, initializes its elements to integers from 1 to N x N, and then prints out the array.

 go(N):-
    new_array(A,[N,N]),
    foreach(I in 1..N,J in 1..N,A[I,J] is (I-1)*N+J),
    foreach(I in 1..N, 
            (foreach(J in 1..N,
                     [E],(E @= A[I,J], format("~4d ",[E]))),nl)).
In the last line, E is declared as a local variable. In B-Prolog, a term like A[I,J] is interpreted as an array access in arithmetic built-ins, in calls to '@='/2, and in constraints, but is interpreted as the term A^[I,J] in any other context. That is why users can use A[I,J] is (I-1)*N+J to bind an array element, but cannot use write(A[I,J]) to print an element.

As seen in the examples, foreach(T in ([a,b,c],1..3),writeln(T)) and foreach((A,N) in ([a,b,c],1..3),writeln((A=N)), the base foreach can be used to easily iterate over multiple collections simultaneously.



Neng-Fa Zhou 2013-01-25