2.56 Exercise 2.56
The definitions of exponentiation?, base, and exponent are
trivial, basically identical to similar procedures for other operations:
| (define (exponentiation? x) | | (and (pair? x) (eq? (car x) '**))) |
|
| (define (base x) (cadr x)) |
| (define (exponent x) (caddr x)) |
make-exponentiation also follows the template of similar procedures for
sums and products. In addition to the base cases for exponents of 0 and
1 that we were asked to do, I have handled the cases for bases of 0
and 1, as well as the case of a constant raised to a constant power.
| (define (make-exponentiation base exponent) | | (cond ((=number? exponent 0) 1) | | ((=number? exponent 1) base) | | ((=number? base 0) 0) | | ((=number? base 1) 1) | | ((and (number? base) (number? exponent)) | | (expt base exponent)) | | (else (list '** base exponent)))) |
|
However, the rule we are implementing only refers to expressions being raised
to constant powers. We could check that the exponent is a number in
make-exponentiation, but this would be improper for expressions with
non-constant-power exponents that we might want to differentiate later. So,
I’ve created another procedure, constant-exponentiation?, that checks if
an expression is an exponentiation with a constant exponent. This procedure is
used inside deriv to implement the power rule. A simple implementation is
as follows:
| (define (constant-exponentiation? x) | | (and (exponentiation? x) (number? (exponent x)))) |
|
TODO: non-simple implementation
Finally, the extended deriv is as follows:
| (define (variable? x) (symbol? x)) |
| (define (same-variable? v1 v2) | | (and (variable? v1) (variable? v2) (eq? v1 v2))) |
|
| (define (=number? exp num) | | (and (number? exp) (= exp num))) |
|
| (define (make-sum a1 a2) | | (cond ((=number? a1 0) a2) | | ((=number? a2 0) a1) | | ((and (number? a1) (number? a2)) (+ a1 a2)) | | (else (list '+ a1 a2)))) |
|
| (define (make-product m1 m2) | | (cond ((or (=number? m1 0) (=number? m2 0)) 0) | | ((=number? m1 1) m2) | | ((=number? m2 1) m1) | | ((and (number? m1) (number? m2)) (* m1 m2)) | | (else (list '* m1 m2)))) |
|
| (define (sum? x) | | (and (pair? x) (eq? (car x) '+))) |
|
| (define (addend s) (cadr s)) |
| (define (augend s) (caddr s)) |
| (define (product? x) | | (and (pair? x) (eq? (car x) '*))) |
|
| (define (multiplier p) (cadr p)) |
| (define (multiplicand p) (caddr p)) |
| (define (deriv exp var) | | (cond ((number? exp) 0) | | ((variable? exp) | | (if (same-variable? exp var) 1 0)) | | ((sum? exp) | | (make-sum (deriv (addend exp) var) | | (deriv (augend exp) var))) | | ((product? exp) | | (make-sum | | (make-product (multiplier exp) | | (deriv (multiplicand exp) var)) | | (make-product (deriv (multiplier exp) var) | | (multiplicand exp)))) | | ((constant-exponentiation? exp) | | (make-product | | (make-product | | (exponent exp) | | (make-exponentiation (base exp) | | (- (exponent exp) 1))) | | (deriv (base exp) var))) | | (else | | (error "unknown expression type -- DERIV" exp)))) |
|