 0
 0 
In particular:
Àny binding is rolled back on success because it happens behind the "\+ wall":
?- forall(true,X=1),write(X). _4984 true.
And binding previously extant is used of course:
?- X=1,forall(true,X=1),write(X). 1 X = 1. ?- X=2,forall(true,X=1),write(X). false.
forany/2
This should do it:
forany(Cond,Action) :- \+forall(Cond,\+Action).
Make sure you generator doesn't fail
If the generator fails, then forall/2 succeeds (logically correct - but maybe not what you want):
We want:
?- forall(member(X,[_,1,_]),var(X)). false
But due to bad programming we get:
?- forall(member(X,foo),var(X)). true.
The difference between a forall / 2 and a maplist / 2
Consider
repeated_success(X) :-
   between(0,10,X),
   between(X,10,Y),
   format("Success for X=~d, Y=~d~n",[X,Y]).
Then forall does not backtrack over the individual calls if it fails at 11:
?- forall(member(X,[8,9,10,11]),repeated_success(X)). Success for X=8, Y=8 Success for X=9, Y=9 Success for X=10, Y=10 false.
But maplist/2 backtracks if it fails at 11:
?- maplist(repeated_success,[8,9,10,11]). Success for X=8, Y=8 Success for X=9, Y=9 Success for X=10, Y=10 Success for X=9, Y=10 Success for X=10, Y=10 Success for X=8, Y=9 Success for X=9, Y=9 Success for X=10, Y=10 Success for X=9, Y=10 Success for X=10, Y=10 Success for X=8, Y=10 Success for X=9, Y=9 Success for X=10, Y=10 Success for X=9, Y=10 Success for X=10, Y=10 false.
Similarly, for success:
?- forall(member(X,[8,9,10]),repeated_success(X)). Success for X=8, Y=8 Success for X=9, Y=9 Success for X=10, Y=10 true.
But
?- maplist(repeated_success,[8,9,10]). Success for X=8, Y=8 Success for X=9, Y=9 Success for X=10, Y=10 true ; Success for X=9, Y=10 Success for X=10, Y=10 true ; Success for X=8, Y=9 Success for X=9, Y=9 Success for X=10, Y=10 true ; Success for X=9, Y=10 Success for X=10, Y=10 true ; Success for X=8, Y=10 Success for X=9, Y=9 Success for X=10, Y=10 true ; Success for X=9, Y=10 Success for X=10, Y=10 true.
Example
Computing/Verifying prime numbers using forall/2
From http://rosettacode.org/wiki/Primality_by_trial_division#Prolog
prime(2). prime(N) :- between(3, inf, N), 1 is N mod 2, % odd M is floor(sqrt(N+1)), % round-off paranoia Max is (M-1) // 2, % integer division forall( between(1, Max, I), N mod (2*I+1) > 0 ).
Example
Using forall as looping construct to generate side-effects, here a rolling sine wave (works on ANSI terminals because we need to move the cursor to the topleft corner of the drawing N+1 after drawing N has been printed)
% Print a sine wave over a 2*Pi interval vertically using "Lines" lines. The amplitude is
% "Amplitude" characters around the vertical ZERO line (which here is not written using "|"
% but using the last digit of the function's offset, which here is the same as the drawing
% number)
sinus(Lines,Amplitude,Offset,Last) :-
   MaxLine is Lines - 1,
   forall(
      between(0,MaxLine,Line),                              % loop over the lines (i.e. the x values)
      (
         XReal is ( Line + Offset ) * ( 2.0 * pi ) / MaxLine,
         YReal is sin(XReal),
         Height is round(Amplitude*YReal),                  % round to nearest, but outward from 0
                 
         BlankCount is min(Amplitude,Amplitude + Height),
         string_of(' ',BlankCount,BlankString),
         
         StarCount is abs(Height),
         string_of('*',StarCount,StarsString),
   
         format("\x1B[K",[]),   % ANSI sequence to clear current line
         
         write_line(Offset,Height,StarsString,BlankString),
         format("~n",[]),       % End with newline (can't skip this otherwise the line isn't flushed out)
              
         (
            (Last == false, Line == MaxLine)      % If last line but not last drawing, move the cursor back up
            ->
            MoveLeft is BlankCount + StarCount + 1,
            MoveUp is MaxLine + 1,
            format("\x1B[~dD",[MoveLeft]),   % ANSI sequence to move the cursor leftwards
            format("\x1B[~dA",[MoveUp])      % ANSI sequence to move the cursor upwards
            ;
            true
         )
      )
   ).
   
write_line(Offset,Height,StarsString,BlankString) :-
   Of is Offset mod 10,                % instead of '|', write "Offset mod 10" at the X axis for visibility
   format("~s",[BlankString]),
   (Height < 0
    ->
    format("~s~d",[StarsString,Of])    % "negative sinus values"
    ;
    format("~d~s",[Of,StarsString])).  % "positive sinus values"
string_of(Char,Length,String) :-
   length(Chars,Length),
   maplist(=(Char),Chars),
   string_chars(String,Chars).
   
wave(Lines,Amplitude) :-
   MaxDrawings = 10000,
   forall(
      between(0,MaxDrawings,DrawingNumber),                % between 0..MaxDrawings drawings
      (
         Offset = DrawingNumber,                           % the function offset happens to be the same as the drawing number
         (MaxDrawings == DrawingNumber
         -> LastDrawing = true
         ;  LastDrawing = false),
         sinus(Lines,Amplitude,Offset,LastDrawing),        % draw single image
         ((LastDrawing) -> format("~n",[]) ; sleep(0.05))  % slow down a bit between drawings
      )
   ).
Try it for some old-school microcomputer era vibes:
?- wave(30,30).
******************************5
 *****************************5
   ***************************5
       ***********************5
            ******************5
                 *************5
                        ******5
                              5
                              5******
                              5*************
                              5******************
                              5***********************
                              5***************************
                              5*****************************
                              5******************************
                              5******************************
                              5****************************
                              5*************************
                              5*********************
                              5***************
                              5**********
                              5***
                           ***5
                    **********5
               ***************5
         *********************5
     *************************5
  ****************************5
******************************5
******************************5


