DerivacionSimbolica.lsp



;;;;;;;;;;;;;;;
;; Derivada formal

(define (derivada exp var)
  (cond
    ((numero? exp) 0)
    ((variable? exp) (if (misma-variable? exp var) 1 0))
    ((suma? exp) (cons-suma (derivada (primer-sumando  exp) var)
                            (derivada (segundo-sumando exp) var)))
    ((producto? exp) (cons-suma 
                      (cons-producto (derivada (primer-factor exp) var)
                                     (segundo-factor exp))
                      (cons-producto (primer-factor exp)
                                     (derivada (segundo-factor exp) var))))
    (else (error "derivada: el tipo de la expresion es desconocido: " exp))))

;;;;;;;;;;
;; Representacion de las expresiones formales

(define (numero? x) (number? x))

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

(define (misma-variable? x y) 
  (and (variable? x) (variable? y) (eq? x y)))

;;;; sumas
;; constructor

(define (cons-suma s1 s2) (list '+ s1 s2))

;; predicado para reconocer sumas

(define (suma? expresion)
  (and (list? expresion)
       (eq? (first expresion)
            '+)))

;; selectores

(define (primer-sumando z)
  (cadr z))

(define (segundo-sumando z)
  (caddr z))

;;;; productos
;;constructor

(define (cons-producto f1 f2) (list '* f1 f2))

;; predicado para reconocer productos

(define (producto? expresion)
  (and (list? expresion)
       (eq? (first expresion)
            '*)))

;; selectores

(define (primer-factor z)
  (cadr z))

(define (segundo-factor z)
  (caddr z))

;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;
;; Mejoras

#|
(define (cons-suma s1 s2)
  (cond 
    ((and (numero? s1) (numero? s2)) (+ s1 s2))
    ((eq? s1 0) s2)
    ((eq? s2 0) s1)
    (else (list '+ s1 s2))))
|#

#|
(define (cons-producto f1 f2)
  (cond
    ((or (eq? f1 0) (eq? f2 0)) 0)
    ((eq? f1 1) f2)
    ((eq? f2 1) f1)
    ((and (numero? f1) (numero? f2)) (* f1 f2))
    (else (list '* f1 f2))))
|#
(derivada '(+ (+ (* -7 (* x x)) (* 3 x)) 9) 'x)

'(+ (+ (+ (* 0 (* x x)) (* -7 (+ (* 1 x) (* x 1)))) (+ (* 0 x) (* 3 1))) 0)