; takes an expression and a variable and ; returns the derivitive of expr wrt var (define (deriv expr var) (cond ((number? expr) 0) ((variable? expr) (if (same-variable? expr var) 1 0)) ((sum? expr) (make-sum (deriv (sum-arg1 expr) var) (deriv (sum-arg2 expr) var))) ((product? expr) (make-sum (make-product (product-arg1 expr) (deriv (product-arg2 expr) var)) (make-product (product-arg2 expr) (deriv (product-arg1 expr) var)))) (else (error "Unknown type" expr)))) ;; Implementation of lower level ; takes an expression and returns #t ; if it is a variable (define (variable? x) (symbol? x)) ; takes two expressions and is #t if ; they are both the same variable (define (same-variable? x y) (and (variable? x) (variable? y) (eq? x y))) ; takes two expressions and creates a sum ; with them as the arguments -- sums are ; simply represented as lists (define (make-sum x y) (list '+ x y)) ; returns #t if the argument is a sum ; a sum is a list whose first element is ; the symbol + (define (sum? x) (and (pair? x) (eq? (car x) '+))) ; selectors for a sum retrieve ; the first and second arguments ; to be added (define (sum-arg1 x) (cadr x)) (define (sum-arg2 x) (caddr x)) ; takes two expressions and creates a product ; with them as the arguments -- products are ; simply represented as lists (define (make-product x y) (list '* x y)) ; returns #t if the argument is a product ; a product is a list whose first element is ; the symbol * (define (product? x) (and (pair? x) (eq? (car x) '*))) ; selectors for a product retrieve ; the first and second arguments ; to be multiplied (define (product-arg1 x) (cadr x)) (define (product-arg2 x) (caddr x)) ;; some definitions (define expr+ (make-sum 'x 3)) (define expr* (make-product 'x 'y)) (define expr-complicated (make-product expr* expr+)) ; a new constructor that simplifies the sum a bit (define (simp-make-sum x y) (cond ((and (number? x) (= x 0)) y) ((and (number? y) (= y 0)) x) ((and (number? x) (number? y)) (+ x y)) (else (list '+ x y)))) ; a new constructor that simplifies the product a bit (define (simp-make-product x y) (cond ((or (and (number? x) (= x 0)) (and (number? y) (= y 0))) 0) ((and (number? x) (= x 1)) y) ((and (number? y) (= y 1)) x) ((and (number? x) (number? y)) (* x y)) (else (list '* x y))))