3
votes

Hello i try to write recursion that count down like this

in prolog language

i tried to do some code like this:

down(Y,X):- Y>0,K is Y-1,down(K,X).

but its return "false." i dont know why its return boolean result... its need to insert into X the K value... and generaly how to make a recursion that return all the time some number...

what i need to do?

tnx a lot

4

4 Answers

2
votes

It is generally bad practice to throw in side effects (as printing) into your predicates. But on the other hand, your question doesn't make it clear how you want to get the decreasing values.

Either way, here is the logic of a counter:

down(N, N). % the counter value
down(N, X) :-
    succ(N0, N), % one less, until you reach zero
    down(N0, X). % next counter value

You can then either simply query:

?- down(3, X).

or if you prefer, you can print out everything at once:

?- forall( down(3, X), format("X = ~d~n", [X]) ).

See here for a demo that uses SWI-Prolog's SWISH.

Some comments: the use of succ/2 makes sure that the first argument is a non-negative integer. The use of forall/2 for printing demonstrates how to make the side effect explicit.

2
votes

Missing the answer? Here you go!

?- use_module(library(clpfd)).
true.

?- X in 0..5, labeling([down], [X]).
   X = 5
;  X = 4
;  X = 3
;  X = 2
;  X = 1
;  X = 0.
1
votes

As an alternative to @Boris's answer using succ/2 you could also utilize between/3 like this:

down(N, X) :-
   N0 is -N,
   between(N0, 0, X0),
   X is -X0.

Sample query:

?- down(3, X).
X = 3 ;
X = 2 ;
X = 1 ;
X = 0.
0
votes

false is not a Boolean result returned by your rule. It's a result returned by Prolog interpreter itself indicating that it cannot find an answer to your query.

Your down rule says what to do when Y is above zero, but it does not say what to do when Y reaches zero or goes below. In "Prolog speak" your rule is said to be missing the base clause.

Once you add the base clause, your rule would succeed:

down(Y,_) :- Y < 0.

down(Y,X):-
    Y>=0,
    write(X), write(' = '), write(Y), nl,
    K is Y-1,
    down(K,X).

All you need to do now is to ensure that your recursive rule prints something (demo).