In this exercise, we are tasked with modifying the given make-rat
procedure to deal with negative arguments. We can simply do that by checking if the denominator is negative and flipping the digits.
Also, we perform gcd
on the absolute values because the definition of remainder
makes the sign of the answer dependant on the recursion depth. For example,
Due to the inconsistency in the sign of the answer, we perform gcd
on the absolute values to get a consistent GCD. Finally, some test cases.
In this exercise, we are tasked with creating an abstraction to represent a line segment composed of two points which are in turn composed of two numbers: the x and y coordinates. Let us first define point
with a method similar to the fractions.
Next, let us define a segment.
Let us now, go on to define the procedure midpoint-segment
which computes the midpoint of a segment and returns a point.
In this exercise, we are tasked with implementing two different representation for rectangles.
We can define a rectangle uniquely using two diagonally opposite points. For this purpose, we can actually, reuse the point
abstraction from the previous exercise.
Let us test it
We can define a rectangle uniquely using the bottom left point and itd height and width.
Let us test it
In this beautiful exercise, we are tasked with implementing our own version of cdr
based on the given alternative representation as follows:-
To see how the car
procedure works, let us perform substitution. As we have seen, x
and y
have been captured in the definition of z
.
In essense, the cons
procedure takes two arguemnts x
and y
which gives and expression that takes a procedure f
that can work on two arguements. By defining car
to evaluate to the first argument, we get x
. Similarly, cdr
can be implemented by evaluating to q
instead of p
. Let us implement and test them.
In this exercise, we are required to represent pairs of non-negative integers using only number and arithmetic operations by representing a pair of a and b using .
Let us define cons
, car
and cdr
.
Let us test it
In this exercise, we are tasked with implementing Church numerals and defining one
and two
directly without using zero
and add-1
defined below.
Following the hint, let us see what (add-1 zero)
evaluates to.
Thus, we get a procedure which takes a function f
and returns a prodecure which in turn takes an argument x
and evaluates (f x)
.
Looking at the Church numerals wiki page, we can see this matches the description given where and .
Thus, by extension, number n is applies f
n times. We get the following definition of one
and two
:-
Now, we define +-church
to add two Church numerals. Basically, we add the number of times f
is applied in each Church numeral and return a new numeral where f
is applied the sum number of times.
Basically, we unwrap the definition of m
and n
by feeding it f
which gives (lambda (x) (f (f (f ... x))))
Next, we unwrap n
by feeding it x
simply getting (f (f (f ... x)))
.
This in turn gets fed into the unwrapped m
and we get (f (f (f ... x)))
where f
is applied times. Now, this function gets wrapped with lambda (x)
and lambda (f)
to get the original form of Church numeral.
To test this, let us use the inc
function.
Thus, our formulation works.
In this exercise, we are tasked with creating the selector methods for an abstraction representing an interval. This is fairly simple and be done using the following code:-
In this exercise, we are tasked with computing a procedure sub-interval
which takes in two intervals, subtracts one from another and returns an interval. When we subtract an interval from another interval , we get the lowest possible value by subtracting the highest possible value from the lowest possible value and vice versa. Therefore,
Knowing this, we can write the procedure.
In this exercise we are asked to give proof that the width of sum and difference of two intervals is a function only of the respective widths of the two intervals. For this purpose, we take two intervals, and . is used to denote the respective interval width.
When we add two intervals, the following occurs based on its definition
We can see that the width of the summed interval is which is simply the sum of the widths.
When we subtract one interval from another, the following happens
We can see that the width of the subtracted interval is which is simply the difference of the widths.
We can show that widths of multiplied or divided intervals are not a function of widths of the operands. Let us take three intervals , and which have widths 1, 2 and 2 respectively.
Notice that both i2
and i3
have the same width. However, the width of their products and division with i1
are not the same. Thus, we have shown that the width of results for multiplication and division are not a function of the width of the operands.
In this exercise, we are told to modify the div-interval
function such that if we try to divide with an interval that spans zero, an error is registered. This is done simply by performing a check.
We can test this code by using the following test cases:
In this exercise, we are told that we can break the mul-interval
function into 9 different cases for which only one case requires more than two multiplications. When we take an interval, there are three ways that it can be setup in terms of the signs , and . No other combination is possible since lower-bound
is always lower than upper-bound
. Thus, for both intervals, we have a total of nine combinations. Since the multiplication operation is commutative, there are a total of six combinations.
Now, let us write code for this and call it mul-interval-mod
to differentiate it from the original code for testing purposes.
Now let us test this behemoth by comparing with the original mul-interval
.
As can be seen, both answers match. However, the new code is longer and much harder to maintain. We don’t know for sure if we saved on execution time because of the multiple jump statements too. This exercise thus demonstrates the importance of code clarity.
In this exercise, we are tasked with creating procedures to support intervals specified by the center point and the percentage of error. We can reuse the make-center-width
, width
and center
code given in the book. The code for percentage-based interval is as follows:-
In this exercise, we are tasked with investigating if there is a simple formula for approximate percentage tolerance based on the tolerance of the factors.
We are told to make two assumptions:-
Let us take two intervals a and b with tolerances and respectively. Multiplying them and using the rules derived earlier for upper and lower bounds for positive bounds, we get
Since we have assumed that tolerance percentages are small, we know that the value of . Thus, we can ignore the term, arriving at a new interval
Tolerance of the product .
In this exercise we are asked to figure out what went wrong when two algebriacally equivalent forms of resistance equations
and
give two different intervals when evaluated. Let us demonstrate this by using two resistors. and with 1% and 2% tolerances respectively. Let us use par1
and par2
given in the text.
As can be seen, the two methods produce two very different intervals.
Let us see what happens when we evaluate and directly.
We can see that yeilds an interval which is not even centered exactly on one. This means that when we transform equations, we should not assume that the value is one directly. Thus, we start to see where things diverge in both forms of equations.
In this exercise, we are told to determine the validity of the statement that the par2
procedure gives a better result than par1
. Let us see why this is right.
We have seen before that for every operation involving intervals, the width of the interval only increases for all operation and never decreases. Thus, it always makes sense to reduce the overall interval by not involving any interval with a non-zero width. For example the expression is preferable to an equivalent expression simply because of the extra errors being contributed to the resulting interval.
Thus, when we take the expression used in par1
,
we can see that we have 3 operations involving intervals of non-zero width.
Whereas for the expression used in par2
,
we can see that most operations involve a pure number 1, which can be considered an interval of width 0. The only operation involving two intervals of non-zero width is the addition of and . Thus, the result of this procedure has a tighter error bound.
In this exercise, we are tasked with determining if an interval package can be written that can minimize error bounds in interval operations by choosing the appropriate equivalent algebraic form.
In general, equivalent algebraic expressions lead to different answers because of the complex relationship between the results of an interval operation and its arguments. Thus, determining the overall interval of a resulting complex expression gets very difficult.
Looking at the wikipedia article here. We see that this indeed is the case, but we can reduce error by ensuring that each interval appears only once in the expression. This problem is not an easy one to solve for an arbitrary given expression as it might involve symbolic manipulation.
Thus, the best solution is to use expressions which does not have variables repeating.