Ejemplos de la clase 15 ; clase 15 de LPP (05-04-2006) ; ; Funciones básicas que transforman una representación ; en otra ; (define (magnitude-from-real-imag real imag) (sqrt (+ (square real) (square imag)))) (define (angle-from-real-imag real imag) (atan imag real)) (define (real-from-mag-ang r a) (* r (cos a))) (define (imag-from-mag-ang r a) (* r (sin a))) ; ; Datos etiquetados para usar dos representaciones ; (define (attach-tag type-tag contents) (cons type-tag contents)) (define (type-tag datum) (if (pair? datum) (car datum) (error "ad tagged datum -- TYPE-TAG" datum))) (define (contents datum) (if (pair? datum) (cdr datum) (error "ad tagged datum -- CONTENTS" datum))) ; ; La implementacion rectangular ; (define (make-from-real-imag-rectangular x y) (attach-tag 'rectangular (cons x y))) (define (make-from-mag-ang-rectangular r a) (attach-tag 'rectangular (cons (real-from-mag-ang r a) (imag-from-mag-ang r a)))) Copyright © 2006 Depto. de Ciencia de la Computación e IA, Universidad de Alicante All rights reserved. Ejemplos de la clase 15 (define (real-part-rectangular z) (car (contents z))) (define (imag-part-rectangular z) (cdr (contents z))) (define (magnitude-rectangular z) (magnitude-from-real-imag (real-part-rectangular z) (imag-part-rectangular z))) (define (angle-rectangular z) (angle-from-real-imag (real-part-rectangular z) (imag-part-rectangular z))) ; ; La implementacion polar ; (define (make-from-real-imag-polar x y) (attach-tag 'polar (cons (magnitude-from-real-imag x y) (angle-from-real-imag x y)))) (define (make-from-mag-ang-polar r a) (attach-tag 'polar (cons r a))) (define (magnitude-polar z) (car (contents z))) (define (angle-polar z) (cdr (contents z))) (define (real-part-polar z) (real-from-mag-ang (magnitude-polar z) (angle-polar z))) (define (imag-part-polar z) (imag-from-mag-ang (magnitude-polar z) (angle-polar z))) ; ; Selectores genericos ; (define (rectangular? z) (eq? (type-tag z) 'rectangular)) (define (polar? z) (eq? (type-tag z) 'polar)) (define (real-part z) (cond ((rectangular? z) (real-part-rectangular z)) ((polar? z) (real-part-polar z)) (else (error "Unknown type -- REAL-PART" z)))) (define (imag-part z) (cond ((rectangular? z) Page 2 Copyright © 2006 Depto. de Ciencia de la Computación e IA, Universidad de Alicante All rights reserved. Ejemplos de la clase 15 (imag-part-rectangular z)) ((polar? z) (imag-part-polar z)) (else (error "Unknown type -- IMAG-PART" z)))) (define (magnitude z) (cond ((rectangular? z) (magnitude-rectangular z)) ((polar? z) (magnitude-polar z)) (else (error "Unknown type -- MAGNITUDE" z)))) (define (angle z) (cond ((rectangular? z) (angle-rectangular z)) ((polar? z) (angle-polar z)) (else (error "Unknown type -- ANGLE" z)))) ; ; Constructores ; (define (make-from-real-imag x y) (make-from-real-imag-rectangular x y)) (define (make-from-mag-ang r a) (make-from-mag-ang-polar r a)) ; ; Paquete de usuario: add-complex sub-complex mul-complex div-complex ; (define (square x) (* x x)) (define (add-complex z1 z2) (make-from-real-imag (+ (real-part z1) (real-part z2)) (+ (imag-part z1) (imag-part z2)))) (define (sub-complex z1 z2) (make-from-real-imag (- (real-part z1) (real-part z2)) (- (imag-part z1) (imag-part z2)))) (define (mul-complex z1 z2) (make-from-mag-ang (* (magnitude z1) (magnitude z2)) (+ (angle z1) (angle z2)))) (define (div-complex z1 z2) (make-from-mag-ang (/ (magnitude z1) (magnitude z2)) (- (angle z1) (angle z2)))) ; Page 3 Copyright © 2006 Depto. de Ciencia de la Computación e IA, Universidad de Alicante All rights reserved. Ejemplos de la clase 15 ; Otro ejemplo de aplicacion de las operaciones ; genericas con objetos geometricos ; (define pi 3.141592654) (define (make-square side) (attach-tag 'square side)) (define (make-circle radius) (attach-tag 'circle radius)) (define (area shape) (cond ((eq? (type-tag shape) 'square) (* (contents shape) (contents shape))) ((eq? (type-tag shape) 'circle) (* pi (contents shape) (contents shape))) (else (error "Unknown shape -- AREA")))) (define (perimeter shape) (cond ((eq? (type-tag shape) 'square) (* 4 (contents shape))) ((eq? (type-tag shape) 'circle) (* 2 pi (contents shape))) (else (error "Unknown shape -- PERIMETER")))) ;-------------------------------------;3. Programación dirigida por los datos ;-------------------------------------;; Funciones para trabajar con una tabla global ;; (define nil '()) (define (get-primitive key) (let ((record (assq key (cdr the-table)))) (if (not record) nil (cdr record)))) (define (put-primitive key value) (let ((record (assq key (cdr the-table)))) (if (not record) (set-cdr! the-table (cons (cons key value) (cdr the-table))) (set-cdr! record value))) 'ok) (define the-table (list '*table*)) (define (search-value key list) (cond Page 4 Copyright © 2006 Depto. de Ciencia de la Computación e IA, Universidad de Alicante All rights reserved. Ejemplos de la clase 15 ((null? list) #f) ((equal? key (car (car list))) (cdr (car list))) (else (search-value key (cdr list))))) (define (put key1 key2 value) (let ((l-value (get-primitive key1))) (if (pair? l-value) (put-primitive key1 (cons (cons key2 value) l-value)) (put-primitive key1 (list (cons key2 value)))))) (define (get key1 key2) (let ((l-value (get-primitive key1))) (search-value key2 l-value))) ; Ejemplos de uso de estas funciones (put (put (put (get (get (get (put (get 'a 'a 'b 'a 'a 'b 'b 'b 'a 10) 'b 20) 'b 30) 'a) 'b) 'b) 'b (get 'a 'a)) 'b) ; Uso para guardar funciones asociadas a nombre y tipo de dato ;; ;; Actualizo la tabla con las funciones ;; (put (put (put (put (put (put 'real-part 'rectangular real-part-rectangular) 'imag-part 'rectangular imag-part-rectangular) 'magnitude 'rectangular magnitude-rectangular) 'angle 'rectangular angle-rectangular) 'make-from-real-imag 'rectangular make-from-real-imag-rectangular) 'make-from-mag-ang 'rectangular make-from-mag-ang-rectangular) (put (put (put (put (put (put 'real-part 'polar real-part-polar) 'imag-part 'polar imag-part-polar) 'magnitude 'polar magnitude-polar) 'angle 'polar angle-polar) 'make-from-real-imag 'polar make-from-real-imag-polar) 'make-from-mag-ang 'polar make-from-mag-ang-polar) ;; ;; funcion operate ;; (define (operate op obj) (let ((proc (get op (type-tag obj)))) (if proc (proc obj) Page 5 Copyright © 2006 Depto. de Ciencia de la Computación e IA, Universidad de Alicante All rights reserved. Ejemplos de la clase 15 (error "Unknown operator for type")))) Page 6 Copyright © 2006 Depto. de Ciencia de la Computación e IA, Universidad de Alicante All rights reserved.