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)))) |
|