Tema 7 Asignaciones José Antonio Alonso María José Hidalgo Álvaro Romero Dpto. de Ciencias de la Computación e Inteligencia Articial Universidad de Sevilla Asignaciones Contenido: Forma especial set!. El tipo de dato pila. Forma especial do. Programación en estilo imperativo. Procedimientos con memoria. Informática CcIa Asignaciones 7.1 Forma especial set! a (set! a 3) (dene a 3) a (set! a 5) a (dene f (lambda (x) (+ a x))) (f 2) (set! a 0) (f 2) (set! f (lambda (x) (∗ a x))) (f 2) Informática =>reference to undened identier: a =>set!: cannot set undened identier: a =>3 =>5 =>7 =>2 =>0 CcIa Asignaciones 7.2 El tipo de dato pila Ejemplos del uso de pilas: (escribe-pila) =>CIMA: (apila! 'a) (apila! 'b) (apila! 'c) (escribe-pila) =>CIMA: c b a (cima) =>c (escribe-pila) =>CIMA: c b a (desapila!) (escribe-pila) =>CIMA: b a (pila-vacia?) =>#f (desapila!) (desapila!) (pila-vacia?) =>#t (cima) =>cima: la pila está vacía. (desapila!) =>desapila!: la pila está vacía. Informática CcIa Asignaciones 7.3 Implementación del tipo de dato pila (dene pila ()) (dene pila-vacia? (lambda () (null? pila))) (dene apila! (lambda (a) (set! pila (cons a pila)))) (dene desapila! (lambda () (if (pila-vacia?) (error "desapila!: la pila está vacía.") (set! pila (cdr pila))))) Informática CcIa Asignaciones 7.4 Implementación del tipo de dato pila (dene cima (lambda () (if (pila-vacia?) (error "cima: la pila está vacía.") (car pila)))) (dene escribe-pila (lambda () (display "CIMA: ") (for-each (lambda (x) (display x) (display " ")) pila) (newline))) Informática CcIa Asignaciones 7.5 Forma especial do Sintaxis: (do ((variable1 valor-inicial1 paso1) .. .. .. (variableN valor-inicialN pasoN)) (condición-de-parada expresión1 . . . expresiónM) expresión1 .. expresiónK) Informática CcIa Asignaciones 7.6 Procedimiento factorial: estilo imperativo Algoritmo imperativo de factorial: Entrada: N (número natural) Salida: el factorial de N Definir la variable local RES, con valor inicial 1 BUCLE SI N es el número cero ENTONCES devolver el valor de RES FIN EN CASO CONTRARIO hacer RES igual al producto de RES y N disminuir N en 1 IR A BUCLE Informática CcIa Asignaciones 7.7 Procedimiento factorial: estilo imperativo (dene factorial (lambda (n) (let ((res 1)) (do ((m n (− m 1))) ((zero? m) res) (set! res (∗ res m)))))) Informática CcIa Asignaciones 7.8 Procedimiento cuenta-simbolos: estilo imperativo Entrada: L (lista plana) Salida: cantidad de símbolos de L Definir la variable local RES, con valor inicial 0 BUCLE SI L es la lista vacía ENTONCES devolver el valor de RES FIN SI el primer elemento de L es un símbolo ENTONCES aumentar RESP en 1 eliminar el primer elemento de L IR A BUCLE EN CUALQUIER OTRO CASO eliminar el primer elemento de L IR A BUCLE Informática CcIa Asignaciones 7.9 Procedimiento cuenta-simbolos: estilo imperativo (cuenta-simbolos '(1 d e 5 r s)) =>4 (cuenta-simbolos '(w 2 3 e)) =>2 (dene cuenta-simbolos (lambda (l) (let ((resp 0)) (do ((ls l (cdr ls))) ((null? ls) resp) (if (symbol? (car ls)) (set! resp (+ resp 1))))))) Informática CcIa Asignaciones 7.10 Procedimiento cambia: estilo imperativo Algoritmo imperativo de cambia: Entrada: X (dato cualquiera), Y (dato cualquiera) y L (lista) Salida: La lista resultante de cambiar en L las ocurrencias de X de primer nivel por Y Definir la variable local RES, con valor inicial lista vacía BUCLE SI L es la lista vacía ENTONCES devolver el valor de RES FIN SI el primer elemento de L es igual al valor de X ENTONCES añadir el valor de Y a RES, por la derecha eliminar el primer elemento de L IR A BUCLE EN CUALQUIER OTRO CASO añadir el primer elemento de L a RES, por la derecha eliminar el primer elemento de L IR A BUCLE Informática CcIa Asignaciones 7.11 Procedimiento cambia: estilo imperativo (cambia 'a 'b '(c d a b)) =>(c d b b) (cambia 'a 'b '(c d b a b (a c) f)) =>(c d b b b (a c) f) (dene cambia (lambda (x y l) (let ((res ())) (do ((ls l (cdr ls))) ((null? ls) res) (if (equal? (car ls) x) (set! res (append res (list y ))) (set! res (append res (list (car ls))))))))) Informática CcIa Asignaciones 7.12 Procedimiento cuenta-pn: estilo imperativo Entrada: L (lista numérica) Salida: lista con la cantidad de números mayores o iguales que cero y menores que cero que hay en L, en cualquier nivel. Definir las variables locales P y N, ambas con valor inicial 0 BUCLE SI L es la lista vacía ENTONCES devolver la lista con los valores de P y N FIN SI el primer elemento de L es una lista ENTONCES hacer L igual a la lista resultante de juntar el primer elemento de L y el resto de L IR A BUCLE SI el primer elemento de L es mayor o igual que cero ENTONCES aumentar P en 1 eliminar el primer elemento de L IR A BUCLE EN CUALQUIER OTRO CASO aumentar N en 1 eliminar el primer elemento de L IR A BUCLE Informática CcIa Asignaciones 7.13 Procedimiento cuenta-pn: estilo imperativo (cuenta-pn '(0 (-1) ((2 3)))) =>(3 1) (cuenta-pn '((1 (0 -2)) (-3 (((4) 0))) 9)) =>(5 2) (dene cuenta-pn (lambda (l) (let ((p 0) (n 0)) (do ((ls l (if (list? (car ls)) (append (car ls) (cdr ls)) (cdr ls)))) ((null? ls) (list p n)) (cond ((list? (car ls))) ((>= (car ls) 0) (set! p (+ p 1))) (else (set! n (+ n 1)))))))) Informática CcIa Asignaciones 7.14 Procedimientos y entornos locales (dene f (let ((a 2)) (lambda (x) (∗ a x)))) (f 5) =>10 (dene a 3) (f 5) =>10 (dene g (lambda (y ) (let ((a 3)) (f y )))) (g 5) =>10 Informática CcIa Asignaciones 7.15 Los procedimientos assq, assv y assoc (assq (assq (assq (assq (assq 'a '((a 1) (b 2) (c 3))) 'd '((a 1) (b 2) (c 3))) 'b '((a . 1) (b . 2) (c . 3))) 1.0 '((1.0 a) (2.0 b) (3.0 c))) (list 'a) '(((a) 1) ((b) . 2) ((c) 3))) =>(a 1) =>#f =>(b . 2) =>#f =>#f (assv (assv (assv (assv (assv 'a '((a 1) (b 2) (c 3))) 'd '((a 1) (b 2) (c 3))) 'b '((a . 1) (b . 2) (c . 3))) 1.0 '((1.0 a) (2.0 b) (3.0 c))) (list 'a) '(((a) 1) ((b) . 2) ((c) 3))) =>(a 1) =>#f =>(b . 2) =>(1.0 a) =>#f (assoc (assoc (assoc (assoc (assoc Informática 'a '((a 1) (b 2) (c 3))) 'd '((a 1) (b 2) (c 3))) 'b '((a . 1) (b . 2) (c . 3))) 1.0 '((1.0 a) (2.0 b) (3.0 c))) (list 'a) '(((a) 1) ((b) . 2) ((c) 3))) CcIa =>(a 1) =>#f =>(b . 2) =>(1.0 a) =>((a) 1) Asignaciones 7.16 Manejando tablas: el procedimiento procesa (dene exito (lambda (x) (+ 10 (cadr x)))) (dene fracaso (lambda () 'fallo)) (procesa 2 '((1 1) (2 4) (3 9)) exito fracaso) =>14 (procesa 5 '((1 1) (2 4) (3 9)) exito fracaso) =>fallo Denición del procedimiento procesa: (dene procesa (lambda (elto tabla proc-exito proc-fracaso) (let ((par (assoc elto tabla))) (if par (proc-exito par ) (proc-fracaso))))) Informática CcIa Asignaciones 7.17 Procedimientos con memoria (dene memoriza (lambda (proc) (let ((tabla '())) (lambda (arg) (procesa arg tabla (lambda (par ) (cdr par )) (lambda () (let ((val (proc arg))) (set! tabla (cons (cons arg val) tabla)) val))))))) Informática CcIa Asignaciones 7.18 Procedimientos con memoria: b-con-memoria (dene b (lambda (n) (if (< n 2) n (+ (b (− n 1)) (b (− n 2)))))) (dene b-con-memoria (memoriza b)) Comparación de procedimientos: (time (b 20)) => cpu time: 30 real time: 28 gc time: 0 6765 (time (b-con-memoria 20)) => cpu time: 30 real time: 28 gc time: 0 6765 (time (b-con-memoria 20)) => cpu time: 0 real time: 0 gc time: 0 6765 Informática CcIa Asignaciones 7.19 Procedimientos con memoria: b-memorizado (dene b-memorizado (memoriza (lambda (n) (if (< n 2) n (+ (b-memorizado (− n 1)) (b-memorizado (− n 2))))))) Comparación de procedimientos: (time (b-memorizado 150)) => cpu time: 0 real time: 3 gc time: 0 9969216677189303386214405760200 (time (b-memorizado 150)) => cpu time: 0 real time: 0 gc time: 0 9969216677189303386214405760200 (time (b-memorizado 300)) => cpu time: 0 real time: 6 gc time: 0 222232244629420445529739893461909967206666939096499764990979600 Informática CcIa Asignaciones 7.20 Bibliografía [Abelson-96] Cap. 3.1: Assignment and Local State" [Springer-94] Cap. 11: Mutation". Informática CcIa Asignaciones 7.21