2012년 3월 16일 금요일

sicp 2.58


#lang racket
(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))))

(define (variable? x) (symbol? x))

(define (same-variable? v1 v2)
  (and (variable? v1) (variable? v2) (eq? v1 v2)))

(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 (=number? exp num)
  (and (number? exp) (= exp num)))

(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? (cadr x) '+)))

(define (addend s)
  (cond ((equal? (cddr s) '()) 0)
        (else (car s))))

(define (augend s)
  (cond ((equal? (length  (cddr s)) 1) (caddr s))
        (else (cddr s))))

(define (product? x)
  (and (pair? x) (eq? (cadr x) '*)))

(define (multiplier p)
   (car p))

(define (multiplicand p)
  (cond ((equal? (length  (cddr p)) 1) (caddr p))
        (else (cddr p))))

(deriv ' (x + 3 * (x + y + 2)) 'x)
;;(deriv ' (x * (x * y)) 'x)
(deriv ' (x + x) 'x)
(deriv ' (x + x + y + 2) 'x)

(deriv (deriv (deriv ' (x * x * x) 'x) 'x) 'x)

댓글 없음:

댓글 쓰기