You could also do it using a termination case that succeeds:
print_(X) :-
X =< 10,
X1 is X + 1,
write(X), nl,
print_(X1), !.
print_(X) :- X > 10.
Then you get:
| ?- print_(5).
5
6
7
8
9
10
yes
| ?-
Note that this solution, as well as the solution @larsmans presented, will succeed on cases like print_(11)., but just won't display any values.
ADDENDUM@CapelliC presented a very concise solution which will present failure if the initial argument is out of range. Another option, using simple predicates might be:
print_(X) :-
X =< 10,
X1 is X + 1,
write(X), nl,
(print_(X1) -> true ; true).
The last line says, "I don't care whether the query print_(X1) succeeds or fails, I want to succeed and move on." The print_/2 predicate, however, will fail if the argument is initially out of range.
This yields:
| ?- print_(5).
5
6
7
8
9
10
yes
| ?-
And:
| ?- print_(11).
no
| ?-
X =< 10notX <= 10(which would be a syntax error). - lurker