2012년 3월 15일 목요일

sicp 2.57


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

(define (addend s)
  (cond ((equal? (cdr s) '()) 0)
        (else (cadr s))))

(define (augend s)
  (cond ((equal? (cdr s) '()) 0)
        (else (cons (car s) (cddr s)))))

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

(define (multiplier p)
  (cond ((equal? (cdr p) '()) 1)
        (else  (cadr p))))

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

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

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

(equal? (deriv '(* x y (+ x 3)) 'x) (deriv '(* (* x y) (+ x 3)) 'x))

댓글 없음:

댓글 쓰기