A do-loop corresponds to a call to an auxiliary recursive predicate of the form
do__n(...). do__n(...) :- Goals, do__n(...).IterationSpecs is one (or a comma-separated sequence) of the following:
Syntax: The do-operator binds like the semicolon, ie. less than comma. That means that the whole do-construct should always be bracketed.
Unless you use :-pragma(noexpand) or :-dbgcomp, the do-construct is compiled into an efficient auxiliary predicate. By default, the name of this predicate is do__nnn (where nnn is a unique integer), unless you have explicitly specified a name using the loop_name(Name) specifier.
% iterate over list
?- (foreach(X,[1,2,3]) do writeln(X)).
% maplist
?- (foreach(X,[1,2,3]), foreach(Y,List) do Y is X+3).
% sumlist
?- (foreach(X,[1,2,3]), fromto(0,In,Out,Sum) do Out is In+X).
% reverse list
?- (foreach(X,[1,2,3]), fromto([],In,Out,   Rev) do Out=[X|In]).
% reverse list (even shorter)
?- (foreach(X,[1,2,3]), fromto([],In,[X|In],Rev) do true).
% iterate over integers from 1 up to 5
?- (for(I,1,5) do writeln(I)).
% iterate over integers from 1 up to 5
?- (count(I,1,5) do writeln(I)).
% make list of integers [1,2,3,4,5]
?- (for(I,1,5), foreach(I,List) do true).
% make a list of length 3
?- (foreach(_,List), for(_,1,3) do true).
% get the length of a list
?- (foreach(_,[a,b,c]), count(_,1,N) do true).
% actually, the length/2 builtin is (almost)
length(List, N) :- (foreach(_,List), count(_,1,N) do true).
% filter list elements
?- (foreach(X,[5,3,8,1,4,6]), fromto(List,Out,In,[]) do
    X>3 -> Out=[X|In] ; Out=In).
% iterate over structure arguments
?- (foreacharg(X,s(a,b,c,d,e)) do writeln(X)).
% collect args in list
% (bad example, use =.. if you really want to do that!)
?- (foreacharg(X,s(a,b,c,d,e)), foreach(X,List) do true).
% collect args reverse
?- (foreacharg(X,s(a,b,c,d,e)), fromto([],In,[X|In],List) do true).
% or like this:
?- S = s(a,b,c,d,e), functor(S, _, N),
    (for(I,N,1,-1), foreach(A,List), param(S) do arg(I,S,A)).
% The following two are equivalent
?- (foreach(X,[1,2,3])        do             writeln(X)).
?- (fromto([1,2,3],In,Out,[]) do In=[X|Out], writeln(X)).
% The following two are equivalent
?- (count(I,1,5)     do            writeln(I)).
?- (fromto(0,I0,I,5) do I is I0+1, writeln(I)).
% Two examples for nested loops. Print all pairs of list elements:
?- Xs = [1,2,3,4],
    ( foreach(X, Xs), param(Xs) do
	( foreach(Y,Xs), param(X) do
	    writeln(X-Y)
	)
    ).
% and the same without symmetries:
?- Xs = [1,2,3,4],
    ( fromto(Xs, [X|Xs1], Xs1, []) do
	( foreach(Y,Xs1), param(X) do
	    writeln(X-Y)
	)
    ).
% Find all pairs of list elements and collect them in a result list:
pairs(Xs, Ys, Zs) :-
    (
        foreach(X,Xs),
        fromto(Zs, Zs4, Zs1, []),
        param(Ys)
    do
        (
            foreach(Y,Ys),
            fromto(Zs4, Zs3, Zs2, Zs1),
            param(X)
        do
            Zs3 = [X-Y|Zs2]
        )
    ).
# flatten a 2-dimensional matrix into a list
flatten_matrix(Mat, Xs) :-
	dim(Mat, [M,N]),
	(
	    for(I,1,M),
	    fromto(Xs, Xs4, Xs1, []),
	    param(Mat,N)
	do
	    (
		for(J,1,N),
		fromto(Xs4, [X|Xs2], Xs2, Xs1),
		param(Mat,I)
	    do
	    	X is Mat[I,J]
	    )
	).