Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I found this version of Ackermann's function and tried to code it in MIT Scheme Lisp with no success:
The Ackermann Function A(m,n)
When m=0
A(m,n)=n+1
When m>0 and n=0
A(m,n)=A(m-1,1)
When m>0 and n>0
A(m,n)=A(m-1,A(m,n-1))
(found here http://www.gfredericks.com/sandbox/arith/ackermann)
My Scheme code:
(define (acker2 m n)
(cond ((= m 0)
(+ n 1))
((and (> m 0)
(= n 0))
(acker2 (- m 1)
1))
((and (> m 0)
(> n 0))
(acker2 (- m 1)
(acker2 (m
(- n 1)))))))
Now some results:
(acker2 0 0)
value: 1
(acker2 0 1)
value: 2
(acker2 0 2)
value: 3
(acker2 2 2)
object 2 is not applicable
(acker2 1 23)
object 1 is not applicable
(acker2 8 0)
object 7 is not applicable
What's the solution?
There is an error (too many parentheses) in the last expression:
(acker2 (m (- n 1)))
this should be:
(acker2 m (- n 1))
Remember that in Lisp/Scheme (a b1 b2 ...) means “apply the function a to the arguments b1 b2 ...”. The message “object 2 is not applicable” means exactly this: m is equal to 2 and the system tries to apply it to (- n 1). But the number 2 (“the object 2”) is not a function (“is not applicable”).
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 days ago.
Improve this question
I have written the following code to calculate the total rectangular area
(define (make-rect x0 y0 x1 y1)
(list x0 y0 x1 y1))
(define (union-rect rect-list)
(let ((x0 (apply min (map rect-x0 rect-list)))
(y0 (apply min (map rect-y0 rect-list)))
(x1 (apply max (map rect-x1 rect-list)))
(y1 (apply max (map rect-y1 rect-list))))
(make-rect x0 y0 x1 y1)))
(define (total-rect-area rect-list)
(if (= (length rect-list) 1)
(rect-area (car rect-list))
(let ((intersects (rect-list-intersect rect-list)))
(if (or (= (rect-x0 intersects) (rect-x1 intersects))
(= (rect-y0 intersects) (rect-y1 intersects)))
0
(let ((subsets (cdr (power-set intersects))))
(if (= (length subsets) 1)
(rect-area (car subsets))
(let ((areas (map (lambda (subset)
(rect-area (union-rect subset)))
subsets)))
(let ((signs (map (lambda (k)
(if (even? k) 1 -1))
(range (length subsets)))))
(* 1/2 (apply + (map * areas signs)))))))))))
and when give input as
(total-rect-area '((rect 1 1 4 4) (rect 3 3 6 6) (rect 2 2 3 7)))
it gives output as 0 but the thing is my desired output is 20 can anybody help me to find the exact error.
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.
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)
I'm trying recursive functions in z3, and I'm curious if there's a bug with model construction. Consider:
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(f (- x 1))
1))
(check-sat)
(get-value ((f 0)))
Here f is actually the constant function 1, just defined in a silly way. For this input, z3 prints:
sat
(((f 0) 0))
This seems incorrect, since f 0 should equal 1.
What's interesting is if I assert what z3 proposes as the result, then I get the correct unsat answer:
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(f (- x 1))
1))
(assert (= (f 0) 0))
(check-sat)
I get:
unsat
So, it looks like z3 actually does now that f 0 cannot be 0; even though it produced that very model in the previous case.
Taking this one step further, if I issue:
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(f (- x 1))
1))
(assert (= (f 0) 1))
(check-sat)
(get-model)
Then z3 responds:
sat
(model
(define-fun f ((x!0 Int)) Int
1)
)
which is indeed a reasonable answer.
So, it seems perhaps there's a bug with recursive function models under certain conditions?
The models used not to reflect the graph of recursive function definitions.
So when evaluating recursive functions on values that had not been seen during solving it could produce arbitrary results. This behavior is now changed as the recursive definitions are included in models.
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)))))