(defun sum-of-squares-p (n)
(labels ((helper (i sum)
(cond ((= sum n) t)
((> sum n) nil)
((> (* i i) n) nil)
(t (or (helper (+ i 1) (+ sum (* i i)))
(helper (+ i 1) sum))))))
(if (= n 0)
t
(helper 1 0))))
I have this code from my college lesson. Its predicate, which returns t, if number n is sum of squares, which are not the same. E.G.: 10 = 3^2 + 1^2, 9 = 3^2, but 2 != 1^2 + 1^2, cause same same number(1) twice. I have trouble understanding how does this recursion works.
For example: (sum-of-squares-p 10)... steps:
(helper 1 0)
(helper 2 1)
(helper 3 5)
(helper 4 14) -> condition ((> sum n ) nil) = 14 > 10, returns nil and then
the the second expression of or is called ->
- is it called like (helper 1 0) again, or is it called like (helper 5 5)?
Anyways, i have trouble understanding, how does this code sucessfuly T or NIL correctly, and i need your help to understand the process of getting to the result.
Im new to lisp, we only studied very few lessons, we learned only mathematical things in lisp, "if", "cond", "labels", "and", "or", and how to write iterative functions.
Could you please be able to explain me how this recursion deep down works please?
Is there any way to make the predicate easier, maybe with two or more functions?
I tried to write each step of recursion on the paper and didnt get my result.. I tried to write it also iteratively, but didnt work for me.
Common Lisp provides a
tracemacro. LispWorks has an extended version of it, which for example can trace subfunctions.We need to define the function to trace:
Now we need to compile the interpreted function (because we defined it in a LispWorks Listener, which does not compile by default) in LispWorks:
Now we can trace the
helperfunction, which is defined by alabelsconstruct inside thesum-of-squares-pfunction.Calling the function
sum-of-squares-pwill now generate the following trace output: