2013-01-21. 結局自習。
$ git clone https://gist.github.com/4251773.git gu
$ gosh -l ./gu/gu.scm ./*test.scm
| (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)))) | |
| ((exponentation? exp) ;; ex. 2.56 | |
| (make-product | |
| (exponent exp) | |
| (make-exponentation (base exp) (make-sum (exponent exp) -1)))) | |
| (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)) | |
| ((and (sum? a1) (sum? a2)) | |
| (append '(+) (cdr a1) (cdr a2))) | |
| ((sum? a1) (append a1 (list a2))) | |
| ((sum? a2) (append (list '+ a1) (cdr a2))) | |
| (else (list '+ a1 a2)))) | |
| (define (=number? v n) | |
| (and (number? v) (= v n))) | |
| (define (make-product a1 a2) | |
| (cond ((or (=number? a1 0) (=number? a2 0)) 0) | |
| ((=number? a1 1) a2) | |
| ((=number? a2 1) a1) | |
| ((and (product? a1) (product? a2)) | |
| (append '(*) (cdr a1) (cdr a2))) | |
| ((product? a1) (append a1 (list a2))) | |
| ((product? a2) (append (list '* a1) (cdr a2))) | |
| (else (list '* a1 a2)))) | |
| (define (sum? x) | |
| (and (pair? x) (eq? (car x) '+))) | |
| (define (addend s) (cadr s)) | |
| (define (augend s) | |
| (let ((_s (cddr s))) | |
| (cond ((= (length _s) 1) (car _s)) | |
| (else (cons '+ _s))))) | |
| (define (product? x) | |
| (and (pair? x) (eq? (car x) '*))) | |
| (define (multiplier p) (cadr p)) | |
| (define (multiplicand p) | |
| (let ((_p (cddr p))) | |
| (cond ((= (length _p) 1) (car _p)) | |
| (else (cons '* _p))))) | |
| ;; ex. 2.56 | |
| (define (make-exponentation a1 a2) | |
| (cond ((=number? a2 0) 1) | |
| ((=number? a2 1) a1) | |
| (else (list '** a1 a2)))) | |
| (define (exponentation? x) | |
| (and (pair? x) (eq? (car x) '**))) | |
| (define (base x) (cadr x)) | |
| (define (exponent x) (caddr x)) | |
| (load "./2013-01-21.scm") | |
| (assert (variable? 'a) (is #t)) | |
| (assert (same-variable? 'a 'a) (is #t)) | |
| (assert (same-variable? 'a 'b) (is #f)) | |
| (assert (make-sum 'a 'b) (is '(+ a b))) | |
| (assert (make-sum (make-sum 'a 'b) 'c) (is '(+ a b c))) | |
| (assert (make-sum 'a (make-sum 'b 'c)) (is '(+ a b c))) | |
| (assert (sum? (make-sum 'a 'b)) (is #t)) | |
| (assert (sum? 'a) (is #f)) | |
| (assert (addend (make-sum 'a 'b)) (is 'a)) | |
| (assert (augend (make-sum 'a 'b)) (is 'b)) | |
| (assert (addend '(+ a b c)) (is 'a)) | |
| (assert (augend '(+ a b c)) (is '(+ b c))) | |
| (assert (make-product 'a 'b) (is '(* a b))) | |
| (assert (make-product (make-product 'a 'b) 'c) (is '(* a b c))) | |
| (assert (make-product 'a (make-product 'b 'c)) (is '(* a b c))) | |
| (assert (make-product | |
| (make-product 'a 'b) (make-product 'c 'd)) (is '(* a b c d))) | |
| (assert (product? (make-sum 'a 'b)) (is #f)) | |
| (assert (product? (make-product 'a 'b)) (is #t)) | |
| (assert (product? 'a) (is #f)) | |
| (assert (multiplier (make-product 'a 'b)) (is 'a)) | |
| (assert (multiplicand (make-product 'a 'b)) (is 'b)) | |
| (assert (multiplier '(* a b c)) (is 'a)) | |
| (assert (multiplicand '(* a b c)) (is '(* b c))) | |
| (assert (make-exponentation 'a 'b) (is '(** a b))) | |
| (assert (make-exponentation 'a 0) (is 1)) | |
| (assert (make-exponentation 'a 1) (is 'a)) | |
| (assert (exponentation? (make-exponentation 'a 'b)) (is #t)) | |
| (assert (exponentation? (make-product 'a 'b)) (is #f)) | |
| (assert (exponentation? 'a) (is #f)) | |
| (assert (base (make-exponentation 'a 'b)) (is 'a)) | |
| (assert (exponent (make-exponentation 'a 'b)) (is 'b)) | |
| ;; deriv | |
| (assert (deriv '(+ x 3) 'x) (is 1)) | |
| (assert (deriv '(* x y) 'x) (is 'y)) | |
| (assert (deriv '(* (* x y) (+ x 3)) 'x) | |
| (is | |
| '(+ (* x y) | |
| (* y (+ x 3))))) | |
| (assert (deriv '(** u n) 'x) | |
| (is '(* n (** u (+ n -1))))) | |
| ;; ex. 2.57 | |
| (assert (deriv '(* x y (+ x 3)) 'x) | |
| (is | |
| '(+ (* x y) | |
| (* y (+ x 3))))) | |