?-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.