2.73¶
; Section 2.3.2 described a program that performs symbolic differentiation: (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)))) (else (error "unknown expression type: DERIV" exp)))) ; We can regard this program as performing a dispatch on the type of the expression ; to be differentiated. In this situation the “type tag” of the datum is the ; algebraic operator symbol (such as +) and the operation being performed is deriv. ; We can transform this program into data-directed style by rewriting the basic ; derivative procedure as (define (deriv exp var) (cond ((number? exp) 0) ((variable? exp) (if (same-variable? exp var) 1 0)) (else ((get 'deriv (operator exp)) (operands exp) var)))) (define (operator exp) (car exp)) (define (operands exp) (cdr exp)) ; (a) Explain what was done above. Why can’t we assimilate the predicates number? ; and variable? into the data-directed dispatch? ; Ans: ; number? and variable? do not use any operator or operands. Hence there's no need ; of dispatch method ; (b) Write the procedures for derivatives of sums and products, and the auxiliary ; code required to install them in the table used by the program above ; Ans: (define (deriv-sum exp var) (make-sum (deriv (addend exp) var) (deriv (augend exp) var))) (define (deriv-product exp var) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp)))) (deriv (install-deriv) (put 'deriv '+ deriv-sum) (put 'deriv '* deriv-product) 'done) ; (c) Choose any additional differentiation rule that you like, such as the one for ; exponents (Exercise 2.56), and install it in this data-directed system. ; Ans: (define (deriv-expo exp var) (define b (base exp)) (define e (exponent exp)) (make-product e (make-product (make-exp b (make-sum e -1)) (deriv b var)))) (define (install-expo) (put 'deriv '** deriv-expo)) ; (d) In this simple algebraic manipulator the type of an expression is the algebraic ; operator that binds it together. Suppose, however, we indexed the procedures ; in the opposite way, so that the dispatch line in `deriv` looked like ; ; ((get (operator exp) 'deriv) (operands exp) var) ; ; What corresponding changes to the derivative system are required? ; Ans: ; We need to reverse the map (put '+ 'deriv deriv-sum) (put '* 'deriv deriv-product)