These exercises concern streams and delayed evaluation, and provide some practice using them in a remarkable and non-trivial example—computing the decimal digits of π.
Put your answers to these problems in the file pi.scm in your hw4 directory. This file should begin with some definitions from the textbook, which are included here. You should copy these definitions into the top of your file pi.scm (in addition to any other definitions you might find useful before starting the code for the various problems below). This is important: pi.scm should not load any other file—it should be a self-contained file that contains any code it needs.
Also, you should create a separate text file notes.txt to hold more extended discussions of the problems and the code you wrote. (Of course, the code should still be commented in place.)
If you use DrScheme for development, then you will find that cons-stream is not pre-defined for you. Here's what you do: put the following code at the top of your file:
(define-syntax cons-stream
(syntax-rules ()
[(cons-stream head tail)
(cons head (delay tail))]))
But please be careful: This code does not work under UMB Scheme.
So before you pass your paper in, please comment out this code. Otherwise your
entire paper won't work. (In any case, you want to be sure you check your work
with UMB Scheme, so if you have forgotten to do this, you will discover it this way.)
There are five problems in this assignment. The first three are fairly short and relatively easy. The last two are each long and difficult. They are based on an expository paper that you will find on my web site: Computing the Digits in π. Actually, all you really need to read in that paper is Section 8, although you may be interested in looking at other parts as well But you will really need to read and understand all of Section 8. (Well, you don't actually have to completely follow the two proofs in Sections 8.1.1 and 8.2.3, but you should at least read over those two sections to get an understanding of what is going on.)
Section 8 of the paper is adapted from the paper ``Unbounded Spigot Algorithms for the Digits of Pi'', by Jeremy Gibbons, in the American Mathematical Monthly (Vol. 113, Number 4; April 2006).
Please note: nowhere in the code for this assignment do you need to use set! or any other operator that changes the value of a variable. Sometimes colloquially, I write in the paper of "changing the value" of some variable. What that always really means is a recursive call in which the new value is passed. But no variable actually changes its value.
Please be careful about this. The whole point of this assignment is to use streams and recursion. If you read what I have written here carefully and do what I suggest, I think you will be amazed at how simple and clear the code for these procedures is.
(display-n stream n)that prints the first n elements of stream, each on a separate line.
This exercise is pretty simple, provided you follow the suggestion in the book. In fact, if you want, you can forget about checking for the empty stream—we will only use this procedure for infinite streams.
After you get this working (and test it), you should answer the following questions:
(stream-map proc (map <??>
argstreams))))
(apply stream-map proc (map <??>
argstreams))))
Please note: I'm not asking for answers such as "It works", or "It doesn't work". I'm looking for explanations. And the explanations have to be correct. In the past, I have had students write things that not only were wrong, but that they could easily have seen were wrong if they had just tried them out.
A good answer to this question will take some careful explaining. And what I wrote in an earlier assignment still holds: any explanation you give about how Scheme works has to be based explicitly on the Scheme language definition R5RS. If it isn't, then the explanation is almost certainly wrong.
(define ones (cons-stream 1 ones)) (define integers (cons-stream 1 (add-streams ones integers)))
Type in these definitions and verify that they work by using the display-n procedure. Generate the stream notdiv-235 of all integers that are not divisible by any of the numbers 2, 3, or 5. (Use stream-filter.)
The function mult-stream produces a stream which is the decimal representation of the product of m with the number represented by strm. Don't worry about where the decimal point goes for this assignment. (Of course, in practice that would be very important! It's not at all hard to figure out, but it's not what I'm concerned about right here.)
Somewhere in the course of doing this, you will probably need a function which you might want to name
number->list-of-digits
which takes a non-negative integer as input and returns the list of single
digits that make up the decimal representation of that integer. There are
various ways to do this. One way is to use some of the built-in
Scheme functions that operate on strings and characters, such as
number->string
string->list
char->integer
If you do this, please be sure to notice that char->integer returns the
ASCII value of a character, so if the character is "3", for instance, what is
returned from char->integer is not the number 3. So you'll have to
adjust for that as well.
To do this, you will need to have a representation for a 2x2 matrix. A simple list of 4 elements will do. Write a constructor and selectors for this.
You will also need a procedure to multiply matrices. I suggest calling this procedure compose, since "multiply" is overloaded enough as it is.
You will need to produce the original input stream. For a hint on how to do this, look at how we produced the stream integers using add-stream. You will need to notice how each element of the stream is produced from the previous one: you just add the matrix
| 1 4 |
| |
| 0 2 |
to each element of the stream to get the next one. (Make sure you understand
this.) Just as the stream integers was produced from the initial
stream ones, you can build up the stream strm by starting
with the stream all of whose elements are this matrix, and you can construct
this stream in turn the same was as the stream ones was
constructed.
That should enable you to produce strm recursively. (You'll also need a procedure to add matrices. Remember that you add matrices by adding corresponding elements.)