Reputation: 4273
in an exercice I have to write a predicate that prints numbers < N using repeat/0, here is what I have tried :
loop(N) :-
repeat,
write(N), nl,
N is N-1,
write(N),
N > 0,
!.
but it only prints the given number N Endlessly.
Any Idea how to implement this using repeat/0
?? thank you
Upvotes: 1
Views: 6231
Reputation: 3725
A simple way :
loop(N) :-
between(1, N, X),
writeln(X),
X >= N, !.
loop(X).
Upvotes: 0
Reputation: 2162
Abderrahmane asked about how to decrement.
Couple ways to do this. Most people would do
dec(0).
dec(N) :-
write(N), nl,
NewN is N - 1,
dec(NewN).
if you insist on a failure driven loop, how about
dec(N) :-
between(1,N,X),
Dec is 11 - X,
write(Dec), nl,
Dec = 1.
or, and this is ugly and bad style (and slow as molasses):
dec(N) :-
assert(current_n(N)),
repeat,
current_n(Y),
write(Y), nl,
NewY is Y - 1,
retractall(current_n(_)).
assert(current_n(NewY)),
Y > 0.
Upvotes: 1
Reputation: 60024
I would introduce a service predicate
isint(I) :- I = 0 ; isint(T), I is T + 1.
this is needed to scope in a new variable (practically solve the point that Anniepoo highlighted in her first response).
Then I could write
loop(N) :-
repeat,
isint(I),
write(I), nl,
I >= N, !.
Upvotes: 1
Reputation: 4273
I finally got to make it work using the predicate between/3
this is my final code :
loop(N) :-
repeat,
between(1, N, X),
writeln(X),
X = N,
!.
Edit :
as @CookieMonster said, repeat/0
is not needed, so here is the last version of the code :
loop(N) :-
between(1, N, X),
writeln(X),
false.
Upvotes: 2
Reputation: 2162
Your original one doesn't work for various reasons, but in particular
loop(N) :-
repeat,
write(N), nl,
N is N-1, <--- no!
write(N),
N > 0,
!.
"is" unifies if the left side is the mathematical result of the right. the left side will be bound to the right. you can't change the value of a var once you've set it in Prolog.
Upvotes: 2
Reputation: 5645
you can use assert/retract eg
:- dynamic value/1.
loop(N) :-
retractall(value(_)),
assert(value(N)),
repeat,
retract(value(V)),
writeln(V),
V1 is V - 1,
assert(value(V1)),
V = 0,
!.
Upvotes: 2