How to solve negative Power in Lisp - math

Today, we used LISP for the first time in our Artificial Intelligence class. Well, the LISP compiler was not readily available, so we dry run every code.
I am currently having a problem with the POWER function when it is raised to a negative number. I asked the lecturer and he said I should do that myself and boasted he will set it in the exam coming up on Wednesday. I searched online, I found some tutorials saying it will produce an error and you should output a customized error message, just then I remembered Stackoverflow.
Here is a sample program I did already but the power is a positive integer.
(DE POWER (M N)
(COND ((ZEROP N) 1)
(T (TIMES M (POWER M (SUB 1 N)))))
Example
M = 4, N = 3
(POWER 4 3)
(TIMES 4 (POWER 4 2))
(TIMES 4 (TIMES 4 (POWER 4 1)))
(TIMES 4(TIMES 4(TIMES 4 ( POWER 4 0))))
(TIMES 4(TIMES 4 (TIMES 4 1)))
(TIMES 4 (TIMES 4 4))
(TIMES 4 16)
64
Now, how can solve the following using a LISP program?
M = 4, N = -3
Are there any function to tackle negative powers in LISP or is there a systematic step to solve this?

M^(-N) = 1 / (M^N). So you can check for negative N and return 1 / M^(-N).
(DE POWER (M N)
(COND ((ZEROP N) 1)
((< N 0) (/ 1 (POWER M (- 0 N))))
(T (TIMES M (POWER M (SUB 1 N)))))

Related

Scheme - List of Fibonacci numbers up to certain value

I am trying to write a function that creates a list of the fibonacci sequence but stops when a certain value is found in the list, then returns that list (I hope that makes sense).
So for example if I give it fib-list(55), the function should return:
(1 1 2 3 5 8 13 21 34 55)
So it's not the 55th fibonacci number I want, its the list UP TO the value 55.
The code I have for returning the list so far looks like this:
; Create a list of the fibonacci sequence up to n.
(define (fib-list n)
; n = n, f2 = 1, f1 = 1, fs = a list.
(let loop ((n n) (f2 1) (f1 1) (fs (list)))
(cond
; If n = 0, return reversed list.
((zero? n) (reverse fs))
; Check if n is in list. If so, return list.
((equal? n (car fs)) fs)
;Else, find the next fibonacci number and add it to the list.
(else (loop (- n 1) f1 (+ f2 f1) (cons f2 fs))))))
(display (fib-list 55))
My main problem is finding if an element is in the list, because at the moment I just get an error on the line where I am trying to write the ((equal? statement.
The error says:
mcar: contract violation
expected: mpair?
given: '()
I am still very VERY new to Scheme, so my understanding of the language as a whole isn't great. So please be gentle when telling me why my code sucks/doesn't make sense.
(list) creates an empty list, and on the first iteration you get to (car fs), which tries to apply car to an empty list, and that's an error.
Your code seems a bit confused about the nature of n.
Your description says that it's the largest number you want, but you're recursing like you want the n:th Fibonacci number - terminating on (zero? n) and recursing on (- n 1).
When you're recursing you're still looking for numbers up to the same limit.
Thus, you should not decrement your limit and terminate on zero, you should leave the limit alone and terminate when you reach larger numbers.
Here's how I would write it:
The initial list is (1 1)
At each step:
Compute the next fibonacci number
If this is greater than the limit, reverse the accumulator list and return it
Otherwise, cons it to the accumulator and recurse with the "new" last two fibonacci number.
In code:
(define (fib-list n)
(let loop ((f2 1) (f1 1) (fs '(1 1)))
(let ((next (+ f1 f2)))
(if (> next n)
(reverse fs)
(loop f1 next (cons next fs))))))
Here's another way you can do it using continuation-passing style. By adding a continuation parameter to our loop, we effectively create our own return mechanism. One unique property of this implementation is the output list is built in forward order and does not need to be reversed when n reaches zero.
(define (fib-list n)
(let loop ((n n) (a 0) (b 1) (return identity))
(if (zero? n)
(return empty)
(loop (sub1 n)
b
(+ a b)
(lambda (rest) (return (cons a rest)))))))
(fib-list 10)
;; '(0 1 1 2 3 5 8 13 21 34)
Reading your question a little closer, in fib-list(N) you need N to be the stopping condition for your loop, not the Nth term in the list. This is actually easier to implement as there's no need to count the number of terms generated.
(define (fib-list max)
(let loop ((a 0) (b 1) (return identity))
(if (> a max)
(return empty)
(loop b
(+ a b)
(lambda (rest) (return (cons a rest)))))))
(fib-list 55)
;; '(0 1 1 2 3 5 8 13 21 34 55)
(fib-list 1000)
;; '(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987)
What's going wrong with the car function?
The car function takes the first element of a list, but if the list is empty it doesn't have a first element. The fs list starts out as empty. When you try to take the first element of an empty list you get this error message:
> (car (list))
mcar: contract violation
expected: mpair?
given: ()
If the list isn't empty, then it has a first element, and it's fine:
> (car (list 4 5 6))
4
Following what you meant in the comment
However, your comment "Check if n is in list" leads me to believe that (equal? n (car fs)) is not what you want anyway. The function for determining whether an element is in a list is called member.
#!r6rs
(import (rnrs base)
(rnrs lists))
> (if (member 4 (list 1 2 4 8))
"it's in the list"
"go fish")
"it's in the list"
> (if (member 5 (list 1 2 4 8))
"it's in the list"
"go fish")
"go fish"
So with that (equal? n (car fs)) test replaced with (member n fs), your code looks like:
; Create a list of the fibonacci sequence up to n.
(define (fib-list n)
; n = n, f2 = 1, f1 = 1, fs = a list.
(let loop ((n n) (f2 1) (f1 1) (fs (list)))
(cond
; If n = 0, return reversed list.
((zero? n) (reverse fs))
; Check if n is in list. If so, return list.
((member n fs) fs)
;Else, find the next fibonacci number and add it to the list.
(else (loop (- n 1) f1 (+ f2 f1) (cons f2 fs))))))
> (fib-list 55)
(10946 6765 4181 2584 1597 987 610 377 233 144 89 55 34 21 13 8 5 3 2 1 1)
This is not the answer you wanted though; you wanted (1 1 2 3 5 8 13 21 34 55).
Why is the list going past 55?
One of the problems is that the n is shadowed, in the same way that in this expression:
> (let ([n 5])
(let ([n 10])
n))
10
The n in the body refers to 10 instead of 5.
The result is going past 55 because inside the loop n is shadowed and has become a different number. I'm guessing in your comment about "check if n is in list", you meant "check if the original n is in list". To do that you have to rename one of the ns:
> (let ([orig-n 5])
(let ([n 10])
orig-n))
5
In the context of your code:
; Create a list of the fibonacci sequence up to n.
(define (fib-list orig-n)
; n = n, f2 = 1, f1 = 1, fs = a list.
(let loop ((n orig-n) (f2 1) (f1 1) (fs (list)))
(cond
; If n = 0, return reversed list.
((zero? n) (reverse fs))
; Check if orig-n is in list. If so, return list.
((member orig-n fs) fs)
;Else, find the next fibonacci number and add it to the list.
(else (loop (- n 1) f1 (+ f2 f1) (cons f2 fs))))))
> (fib-list 55)
(55 34 21 13 8 5 3 2 1 1)
Reversing
This is closer, but it's reversed. You have two base cases, the (zero? n) case and the (member orig-n fs) case. In one of those it's reversed and in one of them it's not. Changing them both to call reverse fixes it:
; Create a list of the fibonacci sequence up to n.
(define (fib-list orig-n)
; n = n, f2 = 1, f1 = 1, fs = a list.
(let loop ((n orig-n) (f2 1) (f1 1) (fs (list)))
(cond
; If n = 0, return reversed list.
((zero? n) (reverse fs))
; Check if orig-n is in list. If so, return reversed list.
((member orig-n fs) (reverse fs))
;Else, find the next fibonacci number and add it to the list.
(else (loop (- n 1) f1 (+ f2 f1) (cons f2 fs))))))
> (fib-list 55)
(1 1 2 3 5 8 13 21 34 55)
Small numbers
This is correct on large Fibonacci numbers like 55, but it still does something weird on small numbers:
> (fib-list 2)
(1 1)
> (fib-list 3)
(1 1 2)
If you only want it to stop when it gets to orig-n, then maybe the decreasing n argument is not needed, and is actually making it stop too early. Removing it (and removing the zero check for it) makes the member check the only stopping case.
This is dangerous, because it could go into an infinite loop if you give it a non-Fibonacci number as input. However, it fixes the small-number examples:
; Create a list of the fibonacci sequence up to n.
; The `orig-n` MUST be a fibonacci number to begin with,
; otherwise this loops forever.
(define (fib-list orig-n)
; f2 = 1, f1 = 1, fs = a list.
(let loop ((f2 1) (f1 1) (fs (list)))
(cond
; Check if orig-n is in list. If so, return reversed list.
((member orig-n fs) (reverse fs))
;Else, find the next fibonacci number and add it to the list.
(else (loop f1 (+ f2 f1) (cons f2 fs))))))
> (fib-list 55)
(1 1 2 3 5 8 13 21 34 55)
> (fib-list 2)
(1 1 2)
> (fib-list 3)
(1 1 2 3)
And finally, consider what happens vs. what should happen if you give it a number like 56.
> (fib-list 56)
;infinite loop
This is a design decision that you have not specified in your question (yet), but there are ways of solving it either way.
Update: orig-n or greater
I should have specified that I need to check if there is a number that is greater than OR equal to orig-n. Can I still use the member function to check for this or will I need to use something different?
You will have to use something different. Just above member in the documentation is the memp function (you could also use exists in this case). The mem is short for member, and the p is short for "predicate". It determines whether any member of the list matches a certain predicate.
> (if (memp positive? (list -4 -2 -3 5 -1))
"one of them is positive"
"go fish")
"one of them is positive"
> (if (memp positive? (list -4 -2 -3 -5 -1))
"one of them is positive"
"go fish")
"go fish"
> (define (five-or-greater? n)
(>= n 5))
> (if (memp five-or-greater? (list -4 -2 -3 6 -1))
"one of them is equal to 5 or greater"
"go fish")
"one of them is equal to 5 or greater"
> (if (memp five-or-greater? (list -4 -2 -3 4 -1))
"one of them is equal to 5 or greater"
"go fish")
"go fish"
To use it for "orig-n or greater", you would have to define a function like:
(define (orig-n-or-greater? n)
(>= n orig-n))
As a local function inside your main function, so that it can refer to orig-n. Then you can use it like (memp orig-n-or-greater? fs).
; Create a list of the fibonacci sequence up to n.
(define (fib-list orig-n)
(define (orig-n-or-greater? n)
(>= n orig-n))
; f2 = 1, f1 = 1, fs = a list.
(let loop ((f2 1) (f1 1) (fs (list)))
(cond
; Check if orig-n or greater is in list. If so, return reversed list.
((memp orig-n-or-greater? fs) (reverse fs))
;Else, find the next fibonacci number and add it to the list.
(else (loop f1 (+ f2 f1) (cons f2 fs))))))
> (fib-list 3)
(1 1 2 3)
> (fib-list 55)
(1 1 2 3 5 8 13 21 34 55)
> (fib-list 56)
(1 1 2 3 5 8 13 21 34 55 89)

Is there a tco pattern with two accumulating variables?

Just for fun (Project Euler #65) I want to implement the formula
n_k = a_k*n_k-1 + n_k-2
in an efficient way. a_k is either 1 or (* 2 (/ k 3)), depending on k.
I started with a recursive solution:
(defun numerator-of-convergence-for-e-rec (k)
"Returns the Nth numerator of convergence for Euler's number e."
(cond ((or (minusp k)) (zerop k) 0)
((= 1 k) 2)
((= 2 k) 3)
((zerop (mod k 3)) (+ (* 2 (/ k 3) (numerator-of-convergence-for-e-rec (1- k)))
(numerator-of-convergence-for-e-rec (- k 2))))
(t (+ (numerator-of-convergence-for-e-rec (1- k))
(numerator-of-convergence-for-e-rec (- k 2))))))
which works for small k but gets pretty slow for k = 100, obviously.
I have no real idea how to transform this function to a version with could be tail-call optimized. I have seen a pattern using two accumulating variables for fibonacci numbers but fail to transform this pattern to my function.
Is there a general guideline how to transform complex recursions to tco versions or should I implement an iterative solution directly.?
First, note that memoization is probably the simplest way optimize your code: it does not reverse the flow of operations; you call your function with a given k and it goes back to zero to compute the previous values, but with a cache. If however you want to turn your function from recursive to iterative with TCO, you'll have to compute things from zero up to k and pretend you have a constant-sized stack / memory.
Step function
First, write a function which computes current n given k, n-1 and n-2:
(defun n (k n1 n2)
(if (plusp k)
(case k
(1 2)
(2 3)
(t (multiple-value-bind (quotient remainder) (floor k 3)
(if (zerop remainder)
(+ (* 2 quotient n1) n2)
(+ n1 n2)))))
0))
This step should be easy; here, I rewrote your function a little bit but I actually only extracted the part that computes n given the previous n and k.
Modified function with recursive (iterative) calls
Now, you need to call n from k starting from 0 to the maximal value you want to be computed, named m hereafter. Thus, I am going to add a parameter m, which controls when the recursive call stops, and call n recursively with the modified arguments. You can see the arguments are shifted, current n1 is the next n2, etc.
(defun f (m k n1 n2)
(if (< m k)
n1
(if (plusp k)
(case k
(1 (f m (1+ k) 2 n1))
(2 (f m (1+ k) 3 n1))
(t (multiple-value-bind (quotient remainder) (floor k 3)
(if (zerop remainder)
(f m (1+ k) (+ (* 2 quotient n1) n2) n1)
(f m (1+ k) (+ n1 n2) n1)))))
(f m (1+ k) 0 n1))))
That's all, except that you don't want to show this interface to your user. The actual function g properly bootstraps the initial call to f:
(defun g (m)
(f m 0 0 0))
The trace for this function exhibits an arrow ">" shape, which is the case with tail-recursive functions (tracing is likely to inhibit tail-call optimization):
0: (G 5)
1: (F 5 0 0 0)
2: (F 5 1 0 0)
3: (F 5 2 2 0)
4: (F 5 3 3 2)
5: (F 5 4 8 3)
6: (F 5 5 11 8)
7: (F 5 6 19 11)
7: F returned 19
6: F returned 19
5: F returned 19
4: F returned 19
3: F returned 19
2: F returned 19
1: F returned 19
0: G returned 19
19
Driver function with a loop
The part that can be slightly difficult, or make your code hard to read, is when we inject tail-recursive calls inside the original function n. I think it is better to use a loop instead, because:
unlike with the tail-recursive call, you can guarantee that the code will behave as you wish, without worrying whether your implementation will actually optimize tail-calls or not.
the code for the step function n is simpler and only expresses what is happening, instead of detailing how (tail-recursive calls are just an implementation detail here).
With the above function n, you can change g to:
(defun g (m)
(loop
for k from 0 to m
for n2 = 0 then n1
for n1 = 0 then n
for n = (n k n1 n2)
finally (return n)))
Is there a general guideline how to transform complex recursions to
tco versions or should I implement an iterative solution directly?
Find a step function which advances the computation from the base case to the general case, and put intermediate variables as parameters, in particular results from past calls. This function can call itself (in which case it will be tail-recursive, because you have to compute all the arguments first), or simply called in a loop. You have to be careful when computing the initial values, you might have more corner cases than with a simple recursive function.
 See also
Scheme's named let, the RECUR macro in Common Lisp and the recur special form in Clojure.

Why is the recursive function performing better than the iterative function in elisp?

As a test for one of my classes, our teacher asked us to test a recursive and non-recursive approach to the famous Euclidean Algorithm:
Iterative
(defun gcdi (a b)
(let ((x a) (y b) r)
(while (not (zerop y))
(setq r (mod x y) x y y r))
x))
Recursive
(defun gcdr (a b)
(if (zerop b)
a
(gcdr b (mod a b))))
And then I ran a test:
(defun test-iterative ()
(setq start (float-time))
(loop for x from 1 to 100000
do (gcdi 14472334024676221 8944394323791464)) ; Fibonacci Numbers close to 2^64 >:)
(- (float-time) start))
(defun test-recursive ()
(setq start (float-time))
(loop for x from 1 to 100000
do (gcdr 14472334024676221 8944394323791464)) ; Fibonacci Numbers close to 2^64 >:)
(- (float-time) start))
And then I ran the timers:
(test-recursive)
: 1.359128475189209
(test-iterative)
: 1.7059495449066162
So my question is this, why did the recursive test perform faster than the iterative test? Isn't iterative almost always better than recursion? Is elisp an exception to this?
The theoretical answer is that the recursive version is actually tail
recursive and thus should compile to iteration.
However, disassembling
the functions reveals the truth:
byte code for gcdi:
args: (a b)
0 varref a
1 varref b
2 constant nil
3 varbind r
4 varbind y
5 varbind x
6 varref y
7:1 constant 0
8 eqlsign
9 goto-if-not-nil 2
12 constant mod
13 varref x
14 varref y
15 call 2
16 varset r
17 varref y
18 varset x
19 varref r
20 dup
21 varset y
22 goto 1
25:2 varref x
26 unbind 3
27 return
vs
byte code for gcdr:
args: (a b)
0 varref b
1 constant 0
2 eqlsign
3 goto-if-nil 1
6 varref a
7 return
8:1 constant gcdr
9 varref b
10 constant mod
11 varref a
12 varref b
13 call 2
14 call 2
15 return
You can see that the gcdr has almost half as many instructions, but contains two call instructions, which means that ELisp does not, apparently, convert the tail recursive call to iteration.
However, function calls in ELisp are relatively cheap and
thus the recursive version executes faster.
PS. While the question makes sense, and the answer is actually generally applicable (e.g., the same approach is valid for Python and CLISP, inter alia), one should be aware that choosing the right algorithm (e.g., linearithmic merge-sort instead of quadratic bubble-sort) is much more important than "micro-optimizations" of the implementation.
Hmm... indeed that's weird, since Emacs's implementation of function calls (and hence recursion) is not very efficient.
I just evaluated the code below:
(defun sm-gcdi (a b)
(let ((x a) (y b) r)
(while (not (zerop y))
(setq r (mod x y) x y y r))
x))
(defun sm-gcdr (a b)
(if (zerop b)
a
(sm-gcdr b (mod a b))))
(defun sm-test-iterative ()
(let ((start (float-time)))
(dotimes (_ 100000)
(sm-gcdi 14472334024676221 8944394323791464))
(- (float-time) start)))
(defun sm-test-recursive ()
(let ((start (float-time)))
(dotimes (_ 100000)
(sm-gcdr 14472334024676221 8944394323791464))
(- (float-time) start)))
and then tried M-: (sm-test-recursive) and M-: (sm-test-iterative) and sure enough the iterative version is faster for me. I then did M-: (byte-compile 'sm-gcdi) and M-: (byte-compile 'sm-gcdr) and tried again, and the speed difference was even larger.
So your measurements come as a surprise to me: they don't match my expectations, and don't match my tests either.

Recursive function returns sum, struggling to understand why?

The following function was given to me on a review sheet:
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2(mystery(- m 1)(- n 1))))
)))
The first two conditions are simple, it's just the recursive otherwise that's confusing me. It just seems to me that the recursion will continue until they both equal zero, which certainly doesn't return the sum. Can someone provide an explanation?
First, let's format the code a bit better to see what's happening:
(define (mystery m n)
(cond ((= m 0) n)
((= n 0) m)
(else (+ 2 (mystery (- m 1) (- n 1))))))
Now, remember that a cond executes only the action corresponding to the first condition that is true (from top to bottom), the others are ignored. If none of the conditions is true, then the else part is executed. The important thing to remember is that only one action is executed.
In particular, your mystery procedure will stop when either m or n becomes zero, not when both become zero. When one of the two reaches zero, the recursion starts to unwind, returning the sum. You can see this when tracing the execution - for example, in Racket:
(require racket/trace)
(trace mystery)
(mystery 3 2)
>(mystery 3 2)
> (mystery 2 1)
> >(mystery 1 0)
< <1
< 3
<5
Just to elaborate on Óscar López's answer (I can't format this in a comment): I find that it's often useful to write these sorts of little recursive maths functions down as if they were maths:
Let m and n be natural numbers, then
n + m = n if m = 0;
n + m = m if n = 0;
n + m = n - 1 + m - 1 + 2;
there are no other cases.
I feel the best way is not to nest but to precompute. Looking at the base case we test with either zero:
(mystery 0 2) ; ==> 2
(nystery 3 0) ; ==> 3
Thus every time at least one argument is zero it returns the other argument. Lets try with a non zero value and remember the second you see a value we have already done before you just switch it with its result:
(mystery 1 3) ; ==
(+ 2 (mystery 0 2)) ; == (we switch known value)
(+ 2 2)
; ==> 4
(mystery 4 1) ; == (we substitute with the expression)
(+ 2 (mystery 3 0)) ; == (we switch known value)
(+ 2 3)
; ==> 5
Since we know the base case always returns the other value we don't need to precalculate it. Here is a go that does that:
(mystery 3 9) ; == (we substitute with the expression)
(+ 2 (mystery 2 8) ; == (we substitute with the expression)
(+ 2 (+ 2 (mystery 1 7))) ; == (we substitute with the expression)
(+ 2 (+ 2 (+ 2 (mystery 0 6))) ; == (we substitute with the expression, n, which is 6)
(+ 2 (+ 2 (+ 2 6))) ; == (we substitute (+ 2 6))
(+ 2 (+ 2 8)) ; == (we substitute (+ 2 8))
(+ 2 10) ; == (we substitute (+ 2 10)
; ==> 12
We can generalize what will happen. The lowest of n and m will decide when the recursion ends. At each step it will add 2 and recurse. Thus it is a fancy way of making:
(define (double-min n m)
(let ((vmin (min n m))
(vmax (max n m)))
(+ (* 2 vmin) (- vmax vmin))))
Which again is a fancy way of adding the two numbers since if n > m, then 2*m+(n-m) = m+m+(n-m) = m+n
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2 (mystery (- m 1) (- n 1))))
)))
First and second conditions are obvious.
Explanation of how the third statement is working:
1 each is taken out of m and n and kept as 2 outside this function.
This is continued till either m is 0 or n is 0.
The first 2 cases are obvious, the sum of 2 numbers where one of the numbers is 0, is equal to the other number.
In the last case, after checking the arguments for 0, we know for sure that both of them are non-0. Assuming that mystery returns the sum of its 2 arguments, then
(+ 2 (mystery (- arg1 1) (- arg2 1)))
will return a sum that is equal to (mystery arg1 arg2) and will eventually halt when one of the arguments is 0, returning the desired result.
Assuming that mystery returns the sum of its 2 arguments is key here and is called the recursive leap of faith. (Google it)

Recursive Addition in Lisp

I'm a beginner and I am trying to teach myself Common Lisp and during my self-study I have written a function that I believe should work for recursive addition of two arguments. However, the function always fails. Why is that?
(defun sum (n m)
;;;Returns the sum of n and m using recursion
(cond ((eq m 0) n))
(sum (1+ n) (1- m)))
As I understand it, it should continually add 1 to n while decrementing m until m is 0 at which point, the recursive addition is complete
I think you have 2 simple typos:
one parenthesis too many and
missing t in your cond clause.
What you probably meant was:
(defun sum (n m)
(cond
((eq m 0) n) ; here you had one parenthesis too many
(t (sum (1+ n) (1- m))))) ; here you were missing the `t` symbol
It's really wierd use case to do such addition, but I'll explain you where is your mistakes:
(defun sum (n m)
;;;Returns the sum of n and m using recursion
(cond ((eq m 0) n)) ;; <= This line is ignored, you not returnin N.
(sum (1+ n) (1- m))) ;; <= this will be called forever
You should write:
(defun sum (n m)
"Recursively increment N and decrement M untill M = 0"
(if (= m 0) ;; don't use EQ for numbers, use EQL or =.
n
(sum (1+ n) (1- m)))) ;; Otherwise recursive call
Let's trace it to see how it works:
CL-USER> (sum 0 10)
0: (SUM 0 10)
1: (SUM 1 9)
2: (SUM 2 8)
3: (SUM 3 7)
4: (SUM 4 6)
5: (SUM 5 5)
6: (SUM 6 4)
7: (SUM 7 3)
8: (SUM 8 2)
9: (SUM 9 1)
10: (SUM 10 0)
10: SUM returned 10
9: SUM returned 10
8: SUM returned 10
7: SUM returned 10
6: SUM returned 10
5: SUM returned 10
4: SUM returned 10
3: SUM returned 10
2: SUM returned 10
1: SUM returned 10
0: SUM returned 10
10
If you'll take an advice - don't try to do such weird things with recursion, if you want to leard how to use it, try it for some natural-recursive cases like factorials, fibonacci, tree processing and such.

Resources