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] ) ).