Scheme if expression returns '#<void>' if the body contains an expression - scheme

So I am currently reading SICP and I am stuck at exercise 1.22, since I do not understand why my program isn't working the way I intend it to work. Here is the Code
#lang sicp
; the given function to time the search for a prime
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
(if (prime? n)
(report-prime (- (runtime) start-time))))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
; finds the smallest natural number that can divide n without any remainder
(define (smallest-divisor n)
(define (square x)
(* x x))
(define (divides? a b)
(= (remainder a b) 0))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? n test-divisor) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(find-divisor n 2))
; returns true if the given number n is prime
(define (prime? n)
(= n (smallest-divisor n)))
; start searching at start and found keeps track of the amount of
; primes found, if it equals 3 return found
(define (search-for-primes start found)
(if (= found 3)
found ; after finding 3 primes above start return
((timed-prime-test start) ; if not continue search with start + 1
(search-for-primes (+ start 1) (if (not (prime? start))
found
(+ found 1))))))
(search-for-primes 1000 0)
The problem is that when I run this program it works fine until it finds a prime number. The interpreter that I use is racket and the program terminates with:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...:
3
1019 *** 0
If I understand the interpreter correctly than it should evaluate this expression according to the applicative-order evaluation principle right? So why is it passing the if expression as a procedure to my search-for-primes procedure? What am I missing here?

The problem is in search-for-primes, if you have more than one expression in one of the legs of an if, then you need to put them inside a begin block - surrounding it with () won't work. This should fix the problem:
(define (search-for-primes start found)
(if (= found 3)
found
(begin ; add this!
(timed-prime-test start)
(search-for-primes (+ start 1) (if (not (prime? start))
found
(+ found 1))))))

Related

Geometric Series function in Scheme language

Im trying to learn scheme and Im having trouble with the arithmetic in the Scheme syntax.
Would anyone be able to write out a function in Scheme that represents the Geometric Series?
You have expt, which is Scheme power procedure. (expt 2 8) ; ==> 256 and you have * that does multiplication. eg. (* 2 3) ; ==> 6. From that you should be able to make a procedure that takes a n and produce the nth number in a specific geometric series.
You can also produce a list with the n first if you instead of using expt just muliply in a named let, basically doing the expt one step at a time and accumulate the values in a list. Here is an example of a procedure that makes a list of numbers:
(define (range from to)
(let loop ((n to) (acc '())
(if (< n from)
acc
(loop (- 1 n) (cons n acc)))))
(range 3 10) ; ==> (3 4 5 6 7 8 9 10)
Notice I'm doing them in reverse. If I cannot do it in reverse I would in the base case do (reverse acc) to get the right order as lists are always made from end to beginning. Good luck with your series.
range behaves exactly like Python's range.
(define (range from (below '()) (step 1) (acc '()))
(cond ((null? below) (range 0 from step))
((> (+ from step) below) (reverse acc))
(else (range (+ from step) below step (cons from acc)))))
Python's range can take only one argument (the upper limit).
If you take from and below as required arguments, the definition is shorter:
(define (range from below (step 1) (acc '()))
(cond ((> (+ from step) below) (reverse acc))
(else (range (+ from step) below step (cons from acc)))))
Here is an answer, in Racket, that you probably cannot submit as homework.
(define/contract (geometric-series x n)
;; Return a list of x^k for k from 0 to n (inclusive).
;; This will be questionable if x is not exact.
(-> number? natural-number/c (listof number?))
(let gsl ((m n)
(c (expt x n))
(a '()))
(if (zero? m)
(cons 1 a)
(gsl (- m 1)
(/ c x)
(cons c a)))))

MIT-Scheme SICP Exercise_1.11 -- object #t is not applicable

This is my first post on StackOverflow. I have been working on Exercise 1.11 from SICP and feel I have a viable solution. In transferring from paper to Emacs I seem to have some syntax error that I am unaware of. I tried my best to double and triple check the parenthesis and solve it but the terminal is still giving me an 'object #t is not applicable' message. Could someone please point me in the right direction of how to fix the code so I can test its output properly?"
Exercise 1.11: A function f
is defined by the rule that:
f(n)=n
if n<3
, and
f(n)=f(n−1)+2f(n−2)+3f(n−3)
if n>=3
Write a procedure that computes f by means of a recursive process.
Write a procedure that computes f by means of an iterative process.
(define (f-recur n)
(if ((< n 3) n)
(+ (f(- n 1))
(* 2 (f(n-2)))
(* 3 (f(n-3)))))
(define (f-iter n)
(define (counter n)
(if (<= n 3) 0)
(- n 3))
(define (d n) (+ n (* 2 n) (* 3 n)))
(define (c n) (+ d (* 2 n) (* 3 n)))
(define (b n) (+ c (* 2 d) (* 3 n)))
(define (a n) (+ b (* 2 c) (* 3 d)))
(define (f a b c d counter)
(if ((> (+ counter 3) n) a)
(f (+ b (* 2 c) (* 3 d)) a b c (+ counter 1)))))
(cond ((= counter 0) d)
((= counter 1) c)
((= counter 2) b)
((= counter 3) a)
(else (f a b c d counter))))
I'm pretty sure SICP is looking for a solution in the manner of this iterative fibonnacci:
(define (fib n)
(define (helper n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))
(helper n 0 1))
Fibonacci is f(n)=f(n−1)+f(n−2) so I guess f(n)=f(n−1)+2f(n−2)+3f(n−3) can be made exactly the same way with one extra variable. Your iterative solution looks more like Fortran than Scheme. Try avoiding set!.

Why does this Miller-Rabin Procedure in Scheme works when the code seems to be wrong?

I am working through SICP. In exercise 1.28 about the Miller-Rabin test. I had this code, that I know is wrong because it does not follow the instrcuccions of the exercise.
(define (fast-prime? n times)
(define (even? x)
(= (remainder x 2) 0))
(define (miller-rabin-test n)
(try-it (+ 1 (random (- n 1)))))
(define (try-it a)
(= (expmod a (- n 1) n) 1))
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(if (and (not (= exp (- m 1))) (= (remainder (square exp) m) 1))
0
(remainder (square (expmod base (/ exp 2) m)) m)))
(else
(remainder (* base (expmod base (- exp 1) m)) m))))
(cond ((= times 0) true)
((miller-rabin-test n) (fast-prime? n (- times 1)))
(else false)))
In it I test if the square of the exponent is congruent to 1 mod n. Which according
to what I have read, and other correct implementations I have seen is wrong. I should test
the entire number as in:
...
(square
(trivial-test (expmod base (/ exp 2) m) m))
...
The thing is that I have tested this, with many prime numbers and large Carmicheal numbers,
and it seems to give the correct answer, though a bit slower. I don't understand why this
seems to work.
Your version of the function "works" only because you are lucky. Try this experiment: evaluate (fast-prime? 561 3) a hundred times. Depending on the random witnesses that your function chooses, sometimes it will return true and sometimes it will return false. When I did that I got 12 true and 88 false, but you may get different results, depending on your random number generator.
> (let loop ((k 0) (t 0) (f 0))
(if (= k 100) (values t f)
(if (fast-prime? 561 3)
(loop (+ k 1) (+ t 1) f)
(loop (+ k 1) t (+ f 1)))))
12
88
I don't have SICP in front of me -- my copy is at home -- but I can tell you the right way to perform a Miller-Rabin primality test.
Your expmod function is incorrect; there is no reason to square the exponent. Here is a proper function to perform modular exponentiation:
(define (expm b e m) ; modular exponentiation
(let loop ((b b) (e e) (x 1))
(if (zero? e) x
(loop (modulo (* b b) m) (quotient e 2)
(if (odd? e) (modulo (* b x) m) x)))))
Then Gary Miller's strong pseudoprime test, which is a strong version of your try-it test for which there is a witness a that proves the compositeness of every composite n, looks like this:
(define (strong-pseudoprime? n a) ; strong pseudoprime base a
(let loop ((r 0) (s (- n 1)))
(if (even? s) (loop (+ r 1) (/ s 2))
(if (= (expm a s n) 1) #t
(let loop ((r r) (s s))
(cond ((zero? r) #f)
((= (expm a s n) (- n 1)) #t)
(else (loop (- r 1) (* s 2)))))))))
Assuming the Extended Riemann Hypothesis, testing every a from 2 to n-1 will prove (an actual, deterministic proof, not just a probabilistic estimate of primality) the primality of a prime n, or identify at least one a that is a witness to the compositeness of a composite n. Michael Rabin proved that if n is composite, at least three-quarters of the a from 2 to n-1 are witnesses to that compositeness, so testing k random bases demonstrates, but does not prove, the primality of a prime n to a probability of 4−k. Thus, this implementation of the Miller-Rabin primality test:
(define (prime? n k)
(let loop ((k k))
(cond ((zero? k) #t)
((not (strong-pseudoprime? n (random (+ 2 (- n 3))))) #f)
(else (loop (- k 1))))))
That always works properly:
> (let loop ((k 0) (t 0) (f 0))
(if (= k 100) (values t f)
(if (prime? 561 3)
(loop (+ k 1) (+ t 1) f)
(loop (+ k 1) t (+ f 1)))))
0
100
I know your purpose is to study SICP rather than to program primality tests, but if you're interested in programming with prime numbers, I modestly recommend this essay at my blog, which discusses the Miller-Rabin test, among other topics. You should also know there are better (faster, less likely to report erroneous result) primality tests available than randomized Miller-Rabin.
It seems to me, you still got correct answer, because in each iteration of expmod you check conditions for previous iteration. You could try to debug exp value using display function inside expmod. Really, your code is not very different from this one.

Scheme Monte-Carlo-Sampling

I am trying to determine the number of marbles that fall within a given circle (radius 1) given that they have random x and y coordinates.
My overall goal is to find an approximate value for pi by using monte carlo sampling by multiplying by 4 the (number of marbles within the circle)/(total number of marbles).
I intended for my function to count the number of marbles within the circle, but I am having trouble following why it does not work. Any help on following the function here would be appreciated.
Please comment if my above request for help is unclear.
(define(monte-carlo-sampling n)
(let ((x (- (* 2 (random)) 1))
(y (- (* 2 (random)) 1)))
(cond((= 0 n)
* 4 (/ monte-carlo-sampling(+ n 1) n)
((> 1 n)
(cond((< 1 (sqrt(+ (square x) (square y))) (+ 1 (monte-carlo-sampling(- n 1)))))
((> 1 (sqrt(+ (square x) (square y))) (monte-carlo-sampling(- n 1))))
)))))
Your parentheses are all messed up, and your argument order for < is wrong. Here's how the code should look like after it's corrected:
(define (monte-carlo-sampling n)
(let ((x (- (* 2 (random)) 1))
(y (- (* 2 (random)) 1)))
(cond ((= n 0)
0)
(else
(cond ((< (sqrt (+ (square x) (square y))) 1)
(+ 1 (monte-carlo-sampling (- n 1))))
(else
(monte-carlo-sampling (- n 1))))))))
This returns the number of hits. You'd have to convert the number of hits into a pi estimate using an outer function, such as:
(define (estimate-pi n)
(* 4 (/ (monte-carlo-sampling n) n)))
Here's how I'd write the whole thing, if it were up to me:
(define (estimate-pi n)
(let loop ((i 0)
(hits 0))
(cond ((>= i n)
(* 4 (/ hits n)))
((<= (hypot (sub1 (* 2 (random)))
(sub1 (* 2 (random)))) 1)
(loop (add1 i) (add1 hits)))
(else
(loop (add1 i) hits)))))
(Tested on Racket, using the definition of hypot I gave in my last answer. If you're not using Racket, you have to change add1 and sub1 to something appropriate.)
I wrote a solution to this problem at my blog; the inner function is called sand because I was throwing grains of sand instead of marbles:
(define (pi n)
(define (sand?) (< (+ (square (rand)) (square (rand))) 1))
(do ((i 0 (+ i 1)) (p 0 (+ p (if (sand?) 1 0))))
((= i n) (exact->inexact (* 4 p (/ n))))))
This converges very slowly; after a hundred thousand iterations I had 3.14188. The blog entry also discusses a method for estimating pi developed by Archimedes over two hundred years before Christ that converges very quickly, with 27 iterations taking us to the bound of double-precision arithmetic.
Here's a general method of doing monte-carlo it accepts as arguments the number of iterations, and a thunk (procedure with no arguments) that should return #t or #f which is the experiment to be run each iteration
(define (monte-carlo trials experiment)
(define (iter trials-remaining trials-passed)
(cond ((= trials-remaining 0)
(/ trials-passed trials))
((experiment)
(iter (- trials-remaining 1) (+ trials-passed 1)))
(else
(iter (- trials-remaining 1) trials-passed))))
(iter trials 0))
Now it's just a mater of writing the specific experiment
You could write in your experiment where experiment is invoked in monte-carlo, but abstracting here gives you a much more flexible and comprehensible function. If you make a function do too many things at once it becomes hard to reason about and debug.
(define (marble-experiment)
(let ((x ...) ;;assuming you can come up with
(y ...)) ;;a way to get a random x between 0 and 1
;;with sufficient granularity for your estimate)
(< (sqrt (+ (* x x) (* y y))) 1)))
(define pi-estimate
(* 4 (monte-carlo 1000 marble-experiment)))

weirdness in scheme

I was trying to implement Fermat's primality test in Scheme.
I wrote a procedure fermat2(initially called fermat1) which returns true
when a^p-1 congruent 1(mod p) (please read it correctly guys!!)
a
every prime p number should satisfy the procedure (And hence Fermat's little theorem .. )
for any a
But when I tried to count the number of times this procedure yields true for a fixed number of trials ... ( using countt procedure, described in code) I got shocking results ans
So I changed the procedure slightly (I don't see any logical change .. may be I'm blind) and named it fermat1(replacing older fermat1 , now old fermat1 ->fermat2) and it worked .. the prime numbers passed the test all the times ...
why on earth the procedure fermat2 called less number of times ... what is actually wrong??
if it is wrong why don't I get error ... instead that computation is skipped!!(I think so!)
all you have to do , to understand what I'm trying to tell is
(countt fermat2 19 100)
(countt fermat1 19 100)
and see for yourself.
Code:
;;Guys this is really weird
;;I might not be able to explain this
;;just try out
;;(countt fermat2 19 100)
;;(countt fermat1 19 100)
;;compare both values ...
;;did you get any error using countt with fermat2,if yes please specify why u got error
;;if it was because of reminder procedure .. please tell your scheme version
;;created on 6 mar 2011 by fedvasu
;;using mit-scheme 9.0 (compiled from source/microcode)
;; i cant use a quote it mis idents (unfriendly stack overflow!)
;;fermat-test based on fermat(s) little theorem a^p-1 congruent to 1 (mod p) p is prime
;;see MIT-SICP,or Algorithms by Vazirani or anyother number theory book
;;this is the correct logic of fermat-test (the way it handles 0)
(define (fermat1 n)
(define (tryout a x)
;; (display "I've been called\n")
(= (remainder (fast-exp a (- x 1)) x) 1))
;;this exercises the algorithm
;;1+ to avoid 0
(define temp (random n))
(if (= temp 0)
(tryout (1+ temp) n)
(tryout temp n)))
;;old fermat-test
;;which is wrong
;;it doesnt produce any error!!
;;the inner procedure is called only selective times.. i dont know when exactly
;;uncomment the display line to see how many times tryout is called (using countt)
;;i didnt put any condition when it should be called
;;rather it should be every time fermat2 is called
;;how is it so??(is it to avoid error?)
(define (fermat2 n)
(define (tryout a x)
;; (display "I've been called\n")
(= (remainder (fast-exp a (- x 1)) x) 1))
;;this exercises the algorithm
;;1+ to avoid 0
(tryout (1+ (random n)) n))
;;this is the dependency procedure for fermat1 and fermat2
;;this procedure calculates base^exp (exp=nexp bcoz exp is a keyword,a primitive)
;;And it is correct :)
(define (fast-exp base nexp)
;;this is iterative procedure where a*b^n = base^exp is constant always
;;A bit tricky though
(define (logexp a b n)
(cond ((= n 0) a);;only at the last stage a*b^n is not same as base^exp
((even? n) (logexp a (square b) (/ n 2)))
(else (logexp (* a b) b (- n 1)))))
(logexp 1 base nexp))
;;utility procedure which takes a procedure and its argument and an extra
;; argument times which tells number of times to call
;;returns the number of times result of applying proc on input num yielded true
;;counting the number times it yielded true
;;procedure yields true for fixed input,
;;by calling it fixed times)
;;uncommenting display line will help
(define (countt proc num times)
(define (pcount p n t c)
(cond ((= t 0)c)
((p n );; (display "I'm passed by fermat1\n")
(pcount p n (- t 1) (+ c 1)));;increasing the count
(else c)))
(pcount proc num times 0))
I had real pain .. figuring out what it actually does .. please follow the code and tell why this dicrepieancies?
Even (countt fermat2 19 100) called twice returns different results.
Let's fix your fermat2 since it's shorter. Definition is: "If n is a prime number and a is any positive integer less than n, then a raised to the nth power is congruent to a modulo n.". That means f(a, n) = a^n mod n == a mod n. Your code tells f(a, n) = a^(n-1) mod n == 1 which is different. If we rewrite this according to definition:
(define (fermat2 n)
(define (tryout a x)
(= (remainder (fast-exp a x) x)
(remainder a x)))
(tryout (1+ (random n)) n))
This is not correct yet. (1+ (random n)) returns numbers from 1 to n inclusive, while we need [1..n):
(define (fermat2 n)
(define (tryout a x)
(= (remainder (fast-exp a x) x)
(remainder a x)))
(tryout (+ 1 (random (- n 1))) n))
This is correct version but we can improve it's readability. Since you're using tryout only in scope of fermat2 there is no need in parameter x to pass n - latter is already bound in scope of tryout, so final version is
(define (fermat n)
(define (tryout a)
(= (remainder (fast-exp a n) n)
(remainder a n)))
(tryout (+ 1 (random (- n 1)))))
Update:
I said that formula used in fermat2 is incorrect. This is wrong because if a*k = b*k (mod n) then a = b (mod n). Error as Vasu pointed was in generating random number for test.

Resources