; Definitionen zum Ableiten von Funktionen
>(define (deriv exp var)    ; leitet exp nach var ab.    ; Invariante : var ist eine variable    (invariant (variable? var))    ; 'body' von deriv    (cond ((constant? exp) 0)          ((variable? exp) (if (same-variables? exp var) 1 0))          (else (deriv-compound exp var))))
>(define (deriv-compound exp var)  (let ((op     (car exp))                    ; Extrahieren des Operators        (first  (cadr exp))                   ; Extrahieren des 1. Operanden        (second (caddr (append exp '(nil))))) ; Extrahieren des 2. Operanden    (case op (+ (make-sum (deriv first var)                          (deriv second var)))             (- (make-diff (deriv first var)                           (deriv second var)))             (*              (make-sum (make-product first  (deriv second var))                        (make-product second (deriv first  var))))             (/              (make-quotient (make-diff (make-product (deriv first var)                                                      second)                                        (make-product (deriv second var)                                                      first))                             (make-product second second)))             ((** expt)              (make-product (deriv first var)    ; innere Ableitung                            (make-product second ; * „užere Ableitung                                          (make-power first                                                      (make-diff second                                                                 1)))))             (sin              (make-product (deriv first var)                            (make-cos first)))             (cos              (make-product (deriv first var)                            (make-diff 0 (make-sin first))))             (tan              (make-product (deriv first var)                            (make-power (make-cos first) -2)))             (ln              (make-product (deriv first var)                            (make-quotient 1 first)))             ;             ; ******************************************             ; *  Hier weitere Operatoren einfgen !!!  *             ; ******************************************             ;             (else (error "Unknown operand : " op)))))

; Hilfspr„dikate !!!
>(define (constant? exp)  (number? exp))
>(define (variable? exp)  (symbol? exp))
>(define (same-variables? v1 v2)  (equal? v1 v2))

<; Konstruktoren !!!;   Die Hauptaufgabe der Konstruktoren ist das Bilden entsprechender Listen.;   (MAKE-SUM a b) ist beispielsweise „quivalent zu (LIST '+ a b). Sind bei-;   de Argumente (a und b) Zahlen, wird gleich die Summe zurckgegeben.  Zum;   Beispiel ergibt (MAKE-SUM 3 4) NICHT (+ 3 4), sondern 7. In der gleichen;   Weise werden noch verschiedene andere Vereinfachungen durchgefhrt.;;   Beispiele:;       (MAKE-SUM '(* 2 x) 0)           -->(* 2 x) ; nicht (+ (* 2 x) 0);       (MAKE-PRODUCT 0 '(+ x y))       -->0       ; nicht (* 0 (+ x y))
>(define (make-sum f s)  (cond ((and (number? f) (number? s)) (+ f s))        ((and (number? f) (zero? f)) s)        ((and (number? s) (zero? s)) f)        ((= f s) (make-product 2 f))        (else (list '+ f s))))
>(define (make-diff f s)  (cond ((and (number? f) (number? s)) (- f s))        ((and (number? f) (zero? f)) (list '- s))        ((and (number? s) (zero? s)) (list '- f))        ((= f s) 0)        (else (list '- f s))))
>(define (make-product f s)  (cond ((and (number? f) (number? s)) (* f s))        ((number? f)         (cond ((zero? f) 0)               ((= f 1)   s)               ((and (not (atom? s)) (equal? (car s) '*))                (cond ((number? (cadr s))  (make-product (* f (cadr s))                                                         (caddr s)))                      ((number? (caddr s)) (make-product (* f (caddr s))                                                         (cadr s)))                      (else (list '* f s))))               (else      (list '* f s))))        ((number? s)         (cond ((zero? s) 0)               ((= s 1)   f)               ((and (not (atom? f)) (equal? (car f) '*))                (cond ((number? (cadr f))  (make-product (* s (cadr f))                                                         (caddr f)))                      ((number? (caddr f)) (make-product (* s (caddr f))                                                         (cadr f)))                      (else (list '* f s))))               (else      (list '* s f))))        ((= s f) (make-power f 2))        (else             (list '* f s))))
>(define (make-quotient f s)  (cond ((and (number? f) (number? s)) (/ f s))        ((number? f)         (cond ((zero? f) 0)               (else      (list '/ f s))))        ((number? s)         (cond ((zero? s) (error "in make-quotient, division by zero"))               ((= s 1)   f)               (else      (list '/ f s))))        ((= f s) 1)        (else (list '/ f s))))
>(define (make-power f s)  (cond ((and (number? f) (number? s)) (expt f s))        ((number? f)         (cond ((zero? f) 0)               ((= f 1)   1)               (else (list '** f s))))        ((number? s)         (cond ((zero? s) 1)               ((= s 1)   f)               (else (list '** f s))))        (else (list '** f s))))
>(define (make-sin f)  (cond ((number? f) (sin f))        (else        (list 'sin f))))
>(define (make-cos f)  (cond ((number? f) (cos f))        (else        (list 'cos f))))
<; Hier weitere Konstruktoren;;   An dieser Stelle sind evtl. weitere vereinfachende Konstruktoren;   einzufgen.

<; Beispiele; ---------;;   Generieren eines Testausdruckes;;   (define expr '(/ (+ (* 3 x) 4) (* x y)))  ; = (3x+4)/(y*y);;   Bilden verschiedener Ableitungen;;   (define expr-dx1 (deriv  expr 'x));   expr-dx1 ist die erste Ableitung von expr nach x.;;   (define expr-dx2 (deriv expr-dx1 'x));   expr-dx2 ist die zweite Ableitung von expr nach x oder;   die erste Ableitung von expr-dx1 nach x.;;   (define expr-dy1 (deriv expr 'y));   expr-dy1 ist die erste Ableitung von expr nach y.;;   (define expr-dz1 (deriv expr 'z));   expr-dz1 ist die erste Ableitung von expr nach z.;   Also ist expr-dz gleich Null !

