Lógica y Programación Curso 2001–2002 Tema 0: Introducción a Lisp José A. Alonso Jiménez Francisco J. Martı́n Mateos José Luis Ruiz Reina Dpto. de Ciencias de la Computación e Inteligencia Artificial Universidad de Sevilla LP 2000–2001 Cc Ia Introducción a Lisp 0.1 Introducción a Lisp x John McCarthy, 1958 x LISt Processing x x u Lambda cálculo u Procesamiento simbólico Lenguaje interpretado u Bucle lee, evalúa, escribe u Compilador Common Lisp u Clisp u GCL x Inteligencia Artificial x Prototipado Rápido x Eficiencia LP 2000–2001 Cc Ia Introducción a Lisp 0.2 Introducción a Lisp x Expresiones > 1 1 > (+ 2 3) 5 > (+ 1 1 1 1 1 1 1 1) 8 > (+ (- 5 2) (* 3 3)) 12 x Primeras observaciones: u Notación prefija: función y argumentos u Expresiones anidadas, paréntesis u Átomos y listas u Sintácticamente simple x Bucle: lee, evalúa, imprime x Salida: > (exit) Bye. Process inferior-lisp finished LP 2000–2001 Cc Ia Introducción a Lisp 0.3 Introducción a Lisp x Evaluación > (+ (- 5 2) (* 3 3)) 12 x Regla de evaluación (básica) u Evaluación de los argumentos u De izquierda a derecha u Los valores se pasan a la función x Todo se evalúa x La función quote: > (quote (+ (- 5 2) (* 3 3))) (+ (- 5 2) (* 3 3)) > ’(+ (- 5 2) (* 3 3)) (+ (- 5 2) (* 3 3)) LP 2000–2001 Cc Ia Introducción a Lisp 0.4 Introducción a Lisp x x Algunos tipos de datos u Enteros: 1, 13, 245 u Sı́mbolos: a, x, juan u Listas: (esto (es) (una lista)) quote para evitar evaluaciones > x *** - EVAL: variable X has no value 1. Break> abort > ’x X > (esto (es) (una lista)) *** - EVAL: undefined function ESTO 1. Break> abort > ’(esto (es) (una lista)) (ESTO (ES) (UNA LISTA)) LP 2000–2001 Cc Ia Introducción a Lisp 0.5 Introducción a Lisp x La lista vacı́a > () NIL > nil NIL > ’() NIL > ’nil NIL x Operaciones con listas > (list ’a (+ 1 2) nil) (A 3 NIL) > (cons ’a ’(b c d)) (A B C D) > (cons ’a (cons ’b nil)) (A B) > (list ’a ’b) (A B) > (car ’(a b c)) A > (cdr ’(a b c)) (B C) > (car (cdr (cdr ’(a b c d)))) C > (caddr ’(a b c)) C > (third ’(a b c d)) C LP 2000–2001 Cc Ia Introducción a Lisp 0.6 Introducción a Lisp x Predicados y valores de verdad u Predicados: > (listp ’(a b c)) T > (listp 27) NIL u El doble papel de nil. Verdad como distinto de nil > (null nil) T > (not nil) T x La forma especial if > (if (listp ’(a b c)) (+ 1 2) (+ 5 6)) 3 > (if (listp 4) (+ 1 2) (+ 5 6)) 11 x Las macros and y or > (and (listp ’(1)) 3 (+ 13 4)) 17 > (or (listp ’(1)) 3 (+ 13 4)) T > (and (listp ’(1)) (listp 1) t) NIL > (or (listp 1) (= 2 3)) NIL LP 2000–2001 Cc Ia Introducción a Lisp 0.7 Introducción a Lisp x Funciones > (defun cuadrado (x) (* x x)) CUADRADO > (cuadrado 3) 9 > (cuadrado 4) 16 x Los programas son funciones u x Piezas que se pueden comprobar individualmente Recursión > (defun pertenece (x l) (if (endp l) ; caso base nil (if (= x (car l)) ; caso base l (pertenece x (cdr l))))) ; recursion PERTENECE > (pertenece 3 ’(1 4 3 5 6)) (3 5 6) > (pertenece 8 ’(1 4 3 5 6)) NIL x Indentación y comentarios LP 2000–2001 Cc Ia Introducción a Lisp 0.8 Introducción a Lisp x Entrada-Salida frente a evaluación x Salida: función format > (format t "~a mas ~a igual a ~a. ~%" 2 3 (+ 2 2 mas 3 igual a 5. NIL x 3)) Entrada: función read > (defun pide (frase) (format t "~a " frase) (read)) PIDE > (pide "Su edad, por favor:") Su edad, por favor: 23 23 x Algunas observaciones u Lectura de expresiones Lisp u Secuencialidad en programas u Efectos colaterales LP 2000–2001 Cc Ia Introducción a Lisp 0.9 Introducción a Lisp x Variables locales y globales > (let ((x 1) (y 2)) (+ x y)) 3 > x *** - EVAL: variable X has no value > (defparameter *glob* 3) *GLOB* > *glob* 3 x Asignaciones con setf > (setf *glob* 98) 98 > (let ((n 10)) (setf n 2) n) 2 > (setf x ’(a b c)) (A B C) > x (A B C) > (setf (car x) ’n) N > x (N B C) > (setf a ’b c ’d e ’f) F > (list a c e) (B D F) LP 2000–2001 Cc Ia Introducción a Lisp 0.10 Introducción a Lisp x El paradigma de la programación funcional u Valores vs. Modificaciones > (setf x ’(a b c d)) (A B C D) > (remove ’b x) (A C D) > x (A B C D) > (setf x (remove ’b x)) (A C D) > x (A C D) u x Programación sin efectos colaterales. Funciones como objetos > (function +) #<SYSTEM-FUNCTION +> > #’+ #<SYSTEM-FUNCTION +> > (apply #’+ ’(1 2 3)) 6 > (funcall #’+ 1 2 3) 6 > (lambda (x) (+ x 100)) #<CLOSURE :LAMBDA (X) (+ X 100)> > ((lambda (x) (+ x 100)) 4) 104 > (funcall #’(lambda (x) (+ x 100)) 4) 104 LP 2000–2001 Cc Ia Introducción a Lisp 0.11 Funciones de manipulación de listas x Listas y pares punteados x Funciones básicas de creación u (CONS X Y) > > > > u (cons (cons (cons (cons ’a ’b) ’a ’(b c)) ’a (cons ’b ’())) ’(a b) ’(c d)) => (A B C) => ((A B) (C D)) => NIL (APPEND L-1 ... L-N) > (append ’(a) ’(b) ’(c) ’(x y)) > (append ’(a b) ’(c d)) u (A . B) (A B C) (A B) ((A B) C D) (LIST X-1 ... X-N) > (list ’a ’b ’c) > (list ’(a b) ’(c d)) > (list) u => => => => => (A B C X Y) => (A B C D) (REVERSE L) > (reverse ’(a (b c) d)) LP 2000–2001 Cc Ia => (D (B C) A) Introducción a Lisp 0.12 Funciones de manipulación de listas x Funciones de acceso a listas u (FIRST L), (CAR L) > (first ’(a b c)) > (first ()) u (REST L), (CDR L) > (rest ’(a b c)) > (rest ()) u => A => NIL => (B C) => NIL (SECOND L) > (second ’(a b c d)) > (second ’(a)) => B => NIL u (THIRD L), (FOURTH L), (FIFTH L), . . . , (TENTH L) u (NTH N L) > (nth u 2 ’(a b c d)) (LAST L) > (last ’(a b c d)) u => (D) (LENGTH L) > (length ’(a (b c) d)) u => C => 3 (NULL X) > (null (rest ’(a b))) > (null (rest ’(a))) LP 2000–2001 Cc Ia => NIL => T Introducción a Lisp 0.13 Funciones aritméticas u (+ X-1 ... X-N) > (+ 3 7 5) > (+) u => 15 => 0 (- X-1 ... X-N) > (- 123 7 5) > (- 3) u => 111 => -3 (* X-1 ... X-N) > (* 2 7 5) > (*) u => 70 => 1 (/ X Y) > (/ 6 2) > (/ 5 2.0) u => 3 => 2.5 (MOD X Y) > (mod 7 2) u => 1 (EXPT X Y) > (expt 2 3) u => 8 (SQRT X) > (sqrt 16) u => 4 (MAX L), (MIN L) > (max 1 3 4 6 2) > (min 1 3 4 6 2) LP 2000–2001 => 6 => 1 Cc Ia Introducción a Lisp 0.14 Valores y operadores lógicos x Valores lógicos: NIL, (), T. x Operadores lógicos: u (NOT X) > (not (= (+ 1 1) 2)) > (not (= (+ 1 1) 3)) u (OR E-1 ... E-N) > (or nil 2 3) > (or (eq ’a ’b) (eq ’a ’c)) u => NIL => T => 2 => NIL (AND E-1 ... E-N) > (and 1 nil 3) > (and 1 2 3) LP 2000–2001 => NIL => 3 Cc Ia Introducción a Lisp 0.15 Predicados aritméticos u (= X-1 ... X-N) > (= 2 2.0 (+ 1 1)) > (= 1 2 1) u (> X-1 ... X-N) > (> 4 3 2 1) > (> 4 3 3 2) u => T => NIL => T => NIL (>= X-1 ... X-N) > (>= 4 3 3 2) > (>= 4 3 3 5) u (< X-1 ... X-N) u (<= X-1 ... X-N) LP 2000–2001 => T => NIL Cc Ia Introducción a Lisp 0.16 Predicados de tipos u (ATOM X) > (atom 3) > (atom ’hola) > (atom ’(1 2 3)) u => T => T => NIL (SYMBOLP X) > (symbolp ’a) > (symbolp 3) u => T => NIL (NUMBERP X) > (numberp 4) > (numberp 3.4) > (numberp ’(1)) u => T => T => NIL (LISTP X) > (listp 3) > (listp nil) > (listp ’(1 2 3)) u => NIL => T => T (CONSP X) > (consp ’(1 . 2)) > (consp nil) > (consp ’(2 5)) LP 2000–2001 Cc Ia => T => NIL => T Introducción a Lisp 0.17 Predicados de igualdad u (EQ X Y) > > > > > u (eq (eq (eq (eq (eq 3 3) 3 3.0) 3.0 3.0) (first ’(a b c)) ’a) (cons ’a ’(b c)) ’(a b c)) T NIL NIL T NIL (EQL X Y) > (eql 3.0 3.0) > (eql (cons ’a ’(b)) (cons ’a ’(b))) u => => => => => => T => NIL (EQUAL X Y) > (equal (cons ’a ’(b)) (cons ’a ’(b))) LP 2000–2001 Cc Ia => T Introducción a Lisp 0.18 Predicado de pertenencia u (MEMBER E L) > > > > > u (member (member (setf l (member (member ’x ’(a x b x c)) ’x ’(a (x) b)) ’((a b) (c d))) ’(c d) l) 2.0 ’(1 2 3)) => => => => => (X B X C) NIL ((A B) (C D)) NIL NIL => => => => => NIL ((C D)) NIL (2 3) (3) (MEMBER E L :TEST <PREDICADO>) > > > > > (member (member (member (member (member LP 2000–2001 ’(c ’(c 2.0 2.0 2.0 d) l) d) l :test #’equal) ’(1 2 3)) ’(1 2 3) :test #’=) ’(1 2 3) :test #’<) Cc Ia Introducción a Lisp 0.19 Condicionales u (IF TEST ENTONCES [EN-CASO-CONTRARIO]) > (if t 1 2) > (if nil 1) u => 1 => NIL (WHEN TEST E-1 ... E-N) > (when t 1 2 3) > (when nil 1 2 3) u (UNLESS TEST E-1 ... E-N) > (unless t 1 2 3) > (unless nil 1 2 3) u => 3 => NIL => NIL => 3 (COND L-1 ... L-N) > (defun notas (n) (cond ((< n 5) ’suspenso) ((< n 7) ’aprobado) ((< n 9) ’notable) (t ’sobresaliente) )) > (notas 8) LP 2000–2001 Cc Ia => NOTAS => NOTABLE Introducción a Lisp 0.20 Definiciones recursivas x Definición de factorial > (defun factorial (n) (if (= n 0) 1 (* n (factorial (- n 1))))) FACTORIAL > (factorial 3) 6 LP 2000–2001 Cc Ia Introducción a Lisp 0.21 Definiciones recursivas u (TRACE F-1 ... F-N) > (trace factorial *) (FACTORIAL *) > (factorial 2) 1. Trace: (FACTORIAL ’2) 2. Trace: (FACTORIAL ’1) 3. Trace: (FACTORIAL ’0) 3. Trace: FACTORIAL ==> 1 3. Trace: (* ’1 ’1) 3. Trace: * ==> 1 2. Trace: FACTORIAL ==> 1 2. Trace: (* ’2 ’1) 2. Trace: * ==> 2 1. Trace: FACTORIAL ==> 2 2 > (untrace) (* FACTORIAL) u (UNTRACE F-1 ... F-N) > (untrace) (* FACTORIAL) LP 2000–2001 Cc Ia Introducción a Lisp 0.22 Variables locales u (LET ((VAR-1 VAL-1)...(VAR-M VAL-M)) E-1 ... E-N) (setf a 9 b 7) (let ((a 2)(b 3)) (+ a b)) (+ a b) (let ((x 2)(y (+ 1 x))) (+ x y)) u => => => => 7 5 16 Error (LET* ((VAR-1 VAL-1) ... (VAR-M VAL-M)) E-1 ... E-N) (let* ((x 2)(y (+ 1 x))) (+ x y)) => LP 2000–2001 Cc Ia 5 Introducción a Lisp 0.23 Recursión en Lisp x Ejemplo: función subconjunto ;;; ;;; ;;; ;;; ;;; ;;; ;;; (SUBCONJUNTO L1 L2) > (subconjunto () ’(s 3 e 4)) T > (subconjunto ’(4 3) ’(s 3 e 4)) T > (subconjunto ’(4 a 3) ’(s 3 e 4)) NIL (defun subconjunto (l1 l2) (if (endp l1) t (and (member (first l1) l2) (subconjunto (rest l1) l2)))) x Ejemplo: función elimina-uno ;;; ;;; ;;; ;;; ;;; ;;; ;;; (ELIMINA-UNO X > (elimina-uno (A B C D) > (elimina-uno (A C D) > (elimina-uno (A C B D) L) 3 ’(a b c d)) ’b ’(a b c d)) ’b ’(a b c b d)) (defun elimina-uno (x l) (cond ((endp l) l) ((equal x (first l)) (rest l)) (t (cons (first l) (elimina-uno x (rest l)))))) LP 2000–2001 Cc Ia Introducción a Lisp 0.24 Recursión en Lisp x Ejemplo: función permutacion ;;; ;;; ;;; ;;; ;;; ;;; ;;; (PERMUTACION L1 L2) > (permutacion ’(x 1 3 4) ’(3 2 x 4)) NIL > (permutacion ’(x 2 3 4) ’(3 2 x 4)) T > (permutacion ’(x 2 3 4) ’(3 2 x 4 4)) NIL (defun permutacion (l1 l2) (cond ((endp l1) (endp l2)) ((member (car l1) l2) (permutacion (rest l1) (elimina-uno (car l1) l2))) (t nil))) x Recursión cruzada: funciones par-p e impar-p (defun par-p (n) (cond ((= n 0) t) ((= n 1) nil) (t (impar-p (- n 1))))) (defun impar-p (n) (cond ((= n 0) nil) ((= n 1) t) (t (par-p (- n 1))))) LP 2000–2001 Cc Ia Introducción a Lisp 0.25 Recursión en Lisp x Ejemplo: función comprime ;;; ;;; ;;; ;;; ;;; (COMPRIME LISTA) > (comprime ’(a a b c c c a d d d d d e)) ((2 A) B (3 C) A (5 D) E) > (comprime ’(a b c c a d e)) (A B (2 C) A D E) (defun comprime (l) (if (consp l) (comprime-aux (first l) 1 (rest l)) l)) (defun comprime-aux (x n l) (if (endp l) (list (n-elementos x n)) (let ((siguiente (car l))) (if (eql x siguiente) (comprime-aux x (+ n 1) (rest l)) (cons (n-elementos x n) (comprime-aux siguiente 1 (rest l))))))) (defun n-elementos (x n) (if (> n 1) (list n x) x)) LP 2000–2001 Cc Ia Introducción a Lisp 0.26 Recursión en Lisp x Recursión profunda: función sustituye ;;; ;;; ;;; ;;; ;;; (SUSTITUYE N V L) > (sustituye ’a ’b ’(f (c b) ((((a (b))))) d)) (F (C A) ((((A (A))))) D) > (sustituye ’a ’b ’(k (b (k (b (k b)))))) (K (A (K (A (K A))))) (defun sustituye (nuevo viejo expr) (cond ((eql expr viejo) nuevo) ((atom expr) expr) (t (cons (sustituye nuevo viejo (first expr)) (sustituye nuevo viejo (rest expr)))))) x Recursión profunda: función member-prof ;;; ;;; ;;; ;;; ;;; ;;; ;;; (MEMBER-PROF X > (member-prof T > (member-prof T > (member-prof NIL L) ’x ’(a (b (c (d (x)))))) ’x ’(x (b (c (d e))))) ’x ’(c (b (c (d))))) (defun member-prof (x l) (cond ((atom l) nil) ((eql x (first l)) t) (t (or (member-prof x (first l)) (member-prof x (rest l)))))) LP 2000–2001 Cc Ia Introducción a Lisp 0.27 Recursión de cola x Función longitud, versión recursiva (defun longitud (l) (if (endp l) 0 (1+ (longitud (rest l))))) > (trace longitud 1+) ;; Tracing function LONGITUD. ;; Tracing function 1+. (LONGITUD 1+) > (longitud ’(a b c)) 1. Trace: (LONGITUD ’(A B C)) 2. Trace: (LONGITUD ’(B C)) 3. Trace: (LONGITUD ’(C)) 4. Trace: (LONGITUD ’NIL) 4. Trace: LONGITUD ==> 0 4. Trace: (1+ ’0) 4. Trace: 1+ ==> 1 3. Trace: LONGITUD ==> 1 3. Trace: (1+ ’1) 3. Trace: 1+ ==> 2 2. Trace: LONGITUD ==> 2 2. Trace: (1+ ’2) 2. Trace: 1+ ==> 3 1. Trace: LONGITUD ==> 3 3 LP 2000–2001 Cc Ia Introducción a Lisp 0.28 Recursión de cola x Función longitud, versión recursiva de cola (defun longitud-it (l &optional (acum 0)) (if (endp l) acum (longitud-it (rest l) (1+ acum)))) > (trace longitud-it 1+) ;; Tracing function LONGITUD-IT. ;; Tracing function 1+. (LONGITUD-IT 1+) > (longitud-it ’(a b c)) 1. Trace: (LONGITUD-IT ’(A B C)) 2. Trace: (1+ ’0) 2. Trace: 1+ ==> 1 2. Trace: (LONGITUD-IT ’(B C) ’1) 3. Trace: (1+ ’1) 3. Trace: 1+ ==> 2 3. Trace: (LONGITUD-IT ’(C) ’2) 4. Trace: (1+ ’2) 4. Trace: 1+ ==> 3 4. Trace: (LONGITUD-IT ’NIL ’3) 4. Trace: LONGITUD-IT ==> 3 3. Trace: LONGITUD-IT ==> 3 2. Trace: LONGITUD-IT ==> 3 1. Trace: LONGITUD-IT ==> 3 3 x Argumentos opcionales (&optional) y claves (&key) LP 2000–2001 Cc Ia Introducción a Lisp 0.29 Recursión de cola x Función n-primeros, versión recursiva ;;; (N-PRIMEROS N L) ;;; > (n-primeros 3 ’(a b c d e)) ;;; (A B C) (defun n-primeros (n l) (if (= n 0) () (cons (car l) (n-primeros (- n 1) (cdr l))))) > (trace n-primeros cons ) ;; Tracing function N-PRIMEROS. ;; Tracing function CONS. (N-PRIMEROS CONS) > (n-primeros 3 ’(a b c d e)) 1. Trace: (N-PRIMEROS ’3 ’(A B C D E)) 2. Trace: (N-PRIMEROS ’2 ’(B C D E)) 3. Trace: (N-PRIMEROS ’1 ’(C D E)) 4. Trace: (N-PRIMEROS ’0 ’(D E)) 4. Trace: N-PRIMEROS ==> NIL 4. Trace: (CONS ’C ’NIL) 4. Trace: CONS ==> (C) 3. Trace: N-PRIMEROS ==> (C) 3. Trace: (CONS ’B ’(C)) 3. Trace: CONS ==> (B C) 2. Trace: N-PRIMEROS ==> (B C) 2. Trace: (CONS ’A ’(B C)) 2. Trace: CONS ==> (A B C) 1. Trace: N-PRIMEROS ==> (A B C) (A B C) LP 2000–2001 Cc Ia Introducción a Lisp 0.30 Recursión de cola x Función n-primeros, versión recursiva de cola (defun n-primeros-aux-it (n l &optional (res ())) (if (= n 0) res (n-primeros-aux-it (- n 1) (rest l) (cons (first l) res)))) (defun n-primeros-it (n l) (reverse (n-primeros-aux-it n l))) > (trace n-primeros-aux-it cons) ;; Tracing function N-PRIMEROS-AUX-IT. ;; Tracing function CONS. (N-PRIMEROS-AUX-IT CONS) > (n-primeros-it 3 ’(a b c d e)) 1. Trace: (N-PRIMEROS-AUX-IT ’3 ’(A B C D E)) 2. Trace: (CONS ’A ’NIL) 2. Trace: CONS ==> (A) 2. Trace: (N-PRIMEROS-AUX-IT ’2 ’(B C D E) ’(A)) 3. Trace: (CONS ’B ’(A)) 3. Trace: CONS ==> (B A) 3. Trace: (N-PRIMEROS-AUX-IT ’1 ’(C D E) ’(B A)) 4. Trace: (CONS ’C ’(B A)) 4. Trace: CONS ==> (C B A) 4. Trace: (N-PRIMEROS-AUX-IT ’0 ’(D E) ’(C B A)) 4. Trace: N-PRIMEROS-AUX-IT ==> (C B A) 3. Trace: N-PRIMEROS-AUX-IT ==> (C B A) 2. Trace: N-PRIMEROS-AUX-IT ==> (C B A) 1. Trace: N-PRIMEROS-AUX-IT ==> (C B A) (A B C) LP 2000–2001 Cc Ia Introducción a Lisp 0.31 Recursión de cola x Función aplana, versión recursiva ;;; ;;; ;;; ;;; ;;; ;;; ;;; (APLANA L) > (aplana ’(a (b (c d) (e (f g)) h) k)) (A B C D E F G H K) > (aplana ’()) NIL > (aplana ’(1 3 4)) (1 3 4) (defun aplana (l) (cond ((endp l) l) ((consp (first l)) (append (aplana (first l)) (aplana (rest l)))) (t (cons (first l) (aplana (rest l)))))) > (trace APLANA APPEND) ;; Tracing function APLANA. ;; Tracing function APPEND. (APLANA APPEND) LP 2000–2001 Cc Ia Introducción a Lisp 0.32 Recursión de cola x Función aplana, versión recursiva, traza > (aplana 1. Trace: 2. Trace: 3. Trace: 4. Trace: 5. Trace: 5. Trace: 4. Trace: 4. Trace: 4. Trace: 4. Trace: 4. Trace: 3. Trace: 2. Trace: 2. Trace: 3. Trace: 4. Trace: 4. Trace: 3. Trace: 2. Trace: 2. Trace: 2. Trace: 1. Trace: (A B C D) LP 2000–2001 ’((a (b)) c d)) (APLANA ’((A (B)) C D)) (APLANA ’(A (B))) (APLANA ’((B))) (APLANA ’(B)) (APLANA ’NIL) APLANA ==> NIL APLANA ==> (B) (APLANA ’NIL) APLANA ==> NIL (APPEND ’(B) ’NIL) APPEND ==> (B) APLANA ==> (B) APLANA ==> (A B) (APLANA ’(C D)) (APLANA ’(D)) (APLANA ’NIL) APLANA ==> NIL APLANA ==> (D) APLANA ==> (C D) (APPEND ’(A B) ’(C D)) APPEND ==> (A B C D) APLANA ==> (A B C D) Cc Ia Introducción a Lisp 0.33 Recursión de cola x Función aplana-it, versión recursiva de cola (defun aplana-it-aux (l &optional (res ())) (cond ((endp l) res) ((consp (first l)) (aplana-it-aux (append (first l) (rest l)) res)) (t (aplana-it-aux (rest l) (cons (first l) res))))) (defun aplana-it (l) (reverse (aplana-it-aux l))) > (trace APLANA-IT-AUX APPEND) ;; Tracing function APLANA-IT-AUX. ;; Tracing function APPEND. (APLANA-IT-AUX APPEND) LP 2000–2001 Cc Ia Introducción a Lisp 0.34 Recursión de cola x Función aplana-it, versión recursiva de cola, traza > (aplana-it ’((a (b)) c d)) 1. Trace: (APLANA-IT-AUX ’((A (B)) C D)) 2. Trace: (APPEND ’(A (B)) ’(C D)) 2. Trace: APPEND ==> (A (B) C D) 2. Trace: (APLANA-IT-AUX ’(A (B) C D) ’NIL) 3. Trace: (APLANA-IT-AUX ’((B) C D) ’(A)) 4. Trace: (APPEND ’(B) ’(C D)) 4. Trace: APPEND ==> (B C D) 4. Trace: (APLANA-IT-AUX ’(B C D) ’(A)) 5. Trace: (APLANA-IT-AUX ’(C D) ’(B A)) 6. Trace: (APLANA-IT-AUX ’(D) ’(C B A)) 7. Trace: (APLANA-IT-AUX ’NIL ’(D C B A)) 7. Trace: APLANA-IT-AUX ==> (D C B A) 6. Trace: APLANA-IT-AUX ==> (D C B A) 5. Trace: APLANA-IT-AUX ==> (D C B A) 4. Trace: APLANA-IT-AUX ==> (D C B A) 3. Trace: APLANA-IT-AUX ==> (D C B A) 2. Trace: APLANA-IT-AUX ==> (D C B A) 1. Trace: APLANA-IT-AUX ==> (D C B A) (A B C D) LP 2000–2001 Cc Ia Introducción a Lisp 0.35 Iteración con DO x Ejemplo ;;; ;;; ;;; ;;; (ESCRIBE-CUADRADOS COMIENZO FINAL) > (escribe-cuadrados 6 9) (6 36) (7 49) (8 64) (9 81) FIN (defun escribe-cuadrados (comienzo final) (do ((i comienzo (1+ i))) ((> i final) ’fin) (format t "\~a " (list i (* i i))))) x La función DO (DO ((VAR-1 VAL-IN-1 VAL-INC-1) .......................... (VAR-N VAL-IN-N VAL-INC-N)) (CONDICION S-1 ... S-M) EXP-1 .... EXP-M’) (1) asigna a la variable VAR-1 el valor VAL-IN-1,..., a la variable VAR-N el valor VAL-IN-N; (2) evalúa la CONDICION; (2.1) si la CONDICION es verdadera, evalúa las expresiones S-1,...,S-M y devuelve el valor de S-M; (2.2) si la CONDICION es falsa, evalúa las expresiones EXP-1,...,EXP-M’; asigna a la variable VAR-1 el valor VAL-INC-1,..., a la variable VAR-N el valor VAL-INC-N y vuelve a (2). LP 2000–2001 Cc Ia Introducción a Lisp 0.36 Iteración con DO x Variantes: DO*, DOLIST, DOTIMES x Ejemplo: exponenciación con DO ;;; ;;; ;;; ;;; ;;; (EXPT-CON-DO M N) > (expt-con-do 2 3) 8 > (expt-con-do 2 0) 1 (defun expt-con-do (m n) (do ((resultado 1 (* m resultado)) (contador n (1- contador))) ((= contador 0) resultado))) x Ejemplo: factorial con DO* ;;; (FACTORIAL-CON-DO* N) ;;; > (factorial-con-do* 3) ;;; 6 (defun factorial-con-do* (n) (do* ((contador n (1- contador)) (resultado n (* resultado contador))) ((= contador 1) resultado))) x Múltiples “contadores” LP 2000–2001 Cc Ia Introducción a Lisp 0.37 Bucles con LOOP x Ejemplos de uso de LOOP: > (let ((res nil)) (loop for x from 1 to 7 do (setf res (cons x res))) res) (7 6 5 4 3 2 1) > (loop for x from 1 to 7 collect (* x x)) (1 4 9 16 25 36 49) > (loop for x from 1 to 7 when (evenp x) collect (* x x)) (4 16 36) > (loop for x from 1 to 7 when (evenp x) summing (* x x)) 56 > (loop for x from 1 to 7 by 2 collect (* x x)) (1 9 25 49) > (loop for x in ’(1 3 5) summing x) 9 LP 2000–2001 Cc Ia Introducción a Lisp 0.38 Bucles con LOOP x Ejemplos: > (let ((x 3) (res nil)) (loop while (> x 0) do (setf res (cons x res) x (- x 1))) res) (1 2 3) > (let ((x 3) (res nil)) (loop until (<= x 0) do (setf res (cons x res) x (- x 1))) res) (1 2 3) > (loop for l in ’((a b c) (d e f) (g h i)) append l) (A B C D E F G H I) LP 2000–2001 Cc Ia Introducción a Lisp 0.39 Bucles con LOOP x Ejemplos: > (defun factor (x) (or (loop for i from 2 to (sqrt x) thereis (when (= (mod x i) 0) i)) x)) FACTOR > (factor 35) 5 > (defun es-primo (x) (= x (factor x))) ES-PRIMO > (es-primo 7) T > (es-primo 35) NIL > (loop for x from 2 to 100 count (es-primo x)) 25 LP 2000–2001 Cc Ia Introducción a Lisp 0.40 Bucles con LOOP x Ejemplos: > (defun primos-gemelos (x) (when (and (es-primo x) (es-primo (+ x 2))) (list x (+ x 2)))) PRIMOS-GEMELOS > (loop for i from 200 to 2000 thereis (primos-gemelos i)) (227 229) > (loop for x from 2 to 100 count (primos-gemelos x)) 8 > (defun suma-primeros-impares (x) (let ((res 0)) (loop until (null x) do (if (= (mod (first x) 2) 0) (return res) (setf res (+ res (first x)) x (rest x)))) res)) SUMA-PRIMEROS-IMPARES > (suma-primeros-impares ’(1 3 2 5 6)) 4 LP 2000–2001 Cc Ia Introducción a Lisp 0.41 Bucles con LOOP x Opciones iniciales: (LOOP FOR <VARIABLE> FROM <INICIO> TO <FIN> ...) (LOOP FOR <VARIABLE> FROM <INICIO> TO <FIN> BY <INCREMENTO> ...) (LOOP FOR <VARIABLE> IN <LISTA> ...) (LOOP WHILE <CONDICION> ...) (LOOP UNTIL <CONDICION> ...) x Opciones centrales: (LOOP ... WHEN <CONDICION> ...) x Opciones finales: (LOOP (LOOP (LOOP (LOOP (LOOP (LOOP (LOOP ... ... ... ... ... ... ... LP 2000–2001 DO <EXPRESION>) COLLECT <EXPRESION>) APPEND <EXPRESION>) THEREIS <EXPRESION>) ALWAYS <EXPRESION>) COUNT <EXPRESION>) SUMMING <EXPRESION>) Cc Ia Introducción a Lisp 0.42 Matrices x Creación: (MAKE-ARRAY DIMENSIONES :INITIAL-ELEMENT ELEMENTO) (MAKE-ARRAY DIMENSIONES :INITIAL-CONTENTS EXPRESION) > (make-array ’(2 2)) #2A((NIL NIL) (NIL NIL)) > (make-array ’(2 1)) #2A((NIL) (NIL)) > (make-array ’(1 2)) #2A((NIL NIL)) > (make-array ’(2 2 1)) #3A(((NIL) (NIL)) ((NIL) (NIL))) > (make-array ’(2 1 2)) #3A(((NIL NIL)) ((NIL NIL))) > (make-array ’(2 2) :initial-element #2A((2 2) (2 2)) > (make-array ’(3 3) :initial-contents ’((a b (1 2 (x y #2A((A B C) (1 2 3) (X Y Z)) > (setf *matriz* (make-array ’(3 3) :initial-contents ’((a (1 (x #2A((A B C) (1 2 3) (X Y Z)) LP 2000–2001 Cc Ia 2) c) 3) z))) b c) 2 3) y z)))) Introducción a Lisp 0.43 Matrices x Acceso: (AREF MATRIZ INDICE-1 ... INDICE-N) > *matriz* #2A((A B C) (1 2 > (aref *matriz* A > (aref *matriz* 2 > (aref *matriz* Z x 3) (X Y Z)) 0 0) 1 1) 2 2) Modificación: (SETF (AREF MATRIZ INDICE-1 ... INDICE-N) EXPRESION) > *matriz-2* #2A((1 2 3) (8 H 4) (7 6 > (setf (aref *matriz-2* H > (setf (aref *matriz-2* 4 > *matriz-2* #2A((A B C) (1 4 H) (X Y LP 2000–2001 Cc Ia 5)) 1 2) ’h) 1 1) 4) Z)) Introducción a Lisp 0.44 Matrices x Ejemplo ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; (SUMA-COLUMNAS MATRIZ) > (setf mat (make-array ’(3 3) :initial-contents ’((1 2 3) (4 5 6) (7 8 9)))) #2A((1 2 3) (4 5 6) (7 8 9)) > (suma-columnas mat) #(12 15 18) (defun suma-columnas (a) (let* ((dim (array-dimensions a)) (f (first dim)) (c (second dim)) (res (make-array (list c)))) (loop for i from 0 to (- c 1) do (setf (aref res i) (loop for j from 0 to (- f 1) summing (aref a j i)))) res)) LP 2000–2001 Cc Ia Introducción a Lisp 0.45 Escritura x La función format (FORMAT DESTINO CADENA-DE-CONTROL X-1 ... X-N) > (format t "~&Linea 1 ~%Linea 2") Linea 1 Linea 2 NIL > (format t "~&El cuadrado de ~a es ~a" 3 (* 3 3)) El cuadrado de 3 es 9 NIL > (setf l ’(a b c)) (A B C) > (format t "~&La longitud de la lista ~a es ~a" l (length l)) La longitud de la lista (A B C) es 3 NIL x Algunas directivas: ~a escribe el siguiente argumento ~& comienza nueva lı́nea, si no está al comienzo de una ~% comienza nueva lı́nea ~Na escribe el siguiente argumento más los espacios suficientes para ocupar N caracteres de ancho LP 2000–2001 Cc Ia Introducción a Lisp 0.46 Lectura x La función read (READ) > (setf a (read)) 2 > a > (* (+ (read) (read)) 3 4 > (read) (+ 2 3) x => 2 => 2 => 7 => (+ 2 3) La función eval: (EVAL EXPRESION) > (eval (read)) (+ 2 2) x => 4 Ejemplo: (defun calcula-cuadrados () (loop (let ((aux (read))) (if (numberp aux) (format t "~&El cuadrado de ~a es ~a~%" aux (* aux aux)) (return ’fin))))) LP 2000–2001 Cc Ia Introducción a Lisp 0.47 Valores de un sı́mbolo x Hemos visto: DATOS EN LISP: - Números: 3, 2.5, - Cadenas: "hola", - Sı́mbolos: adios, - Listas: (1 s 3), - Matrices, etc. x 14.3, ... "el perro come", ... fun, fact, cuadrado, ... (1 (a (b))), ... Un nuevo tipo de dato: funciones. u Expresadas mediante lambda (lambda (x) (* x x)) (lambda (x y) (cond ((> x 0) 1) ((< x 0) -1) (t 0))) x Estos datos se asignan a sı́mbolos: > (setf (symbol-value ’cuadrado) 8) 8 > (setf (symbol-function ’cuadrado) (lambda (x) (* x x))) #<CLOSURE :LAMBDA (X) (* X X)> x Usualmente: > (setf cuadrado 8) 8 > (defun cuadrado (x) (* x x)) CUADRADO LP 2000–2001 Cc Ia Introducción a Lisp 0.48 Evaluación en Lisp x Constantes que no sean listas: el valor representado: 1, 3, "hola" x Lambdas: la función representada (lambda (x) (* 2 x)) x Sı́mbolos (sin quote): su valor como variable > cuadrado x => 8 Quote (’Exp): el valor representado por Exp > ’(cuadrado 4) x => (cuadrado 4) La función function (#’Exp): valor funcional de Exp > #’cuadrado #<CLOSURE :LAMBDA (X) (* X X)> > #’(lambda (x) (* 2 x)) #<CLOSURE :LAMBDA (X) (* 2 X)> LP 2000–2001 Cc Ia Introducción a Lisp 0.49 Evaluación en Lisp x Listas (E1 E2 ... En) u Se evalúa el valor funcional de E1: Si es un sı́mbolo: valor funcional Si es una lambda-expresión: la función que representa u Se evalúan E2,. . . ,En (los argumentos) recursivamente u Se aplica la función obtenida en primer lugar a los valores de los arguementos > (cuadrado 4) 16 > (cuadrado cuadrado) 64 > ((lambda (m n) (+ m n)) (cuadrado 2) cuadrado) 12 LP 2000–2001 Cc Ia Introducción a Lisp 0.50 Funciones como argumentos x La función FUNCALL (FUNCALL FN E-1 ... E-N) > (funcall #’+ 1 2 3) 6 > (funcall #’cuadrado 4) 16 > (funcall #’(lambda (x) (* 2 x)) 3) 6 x La función APPLY (APPLY FN ARGS) > (apply #’+ ’(1 2 3)) 6 > (apply #’max ’(4 5 7)) 7 > (apply #’(lambda (x y) (* 2 x y)) ’(3 4)) 24 x Observaciones: u El primer argumento de funcall y de apply debe ser algo cuyo valor sea una función u Uso de #’ para forzar a obtener el valor funcional u A veces es necesario symbol-function LP 2000–2001 Cc Ia Introducción a Lisp 0.51 Abstracción de procedimientos x Ejemplo: (defun suma-enteros (a b &optional (res 0)) (if (> a b) res (suma-enteros (+ a 1) b (+ a res)))) (defun suma-cubos (a b &optional (res 0)) (if (> a b) res (suma-cubos (+ a 1) b (+ (cubo a) res)))) (defun suma-cubos-pares (a b &optional (res 0)) (if (> a b) res (suma-cubos-pares (+ a 2) b (+ (cubo a) res)))) x Patrón común (defun <NOMBRE> (a b &optional (res 0)) (if (> a b) res (<NOMBRE> <INCREMENTO-A> b (+ <F-A> res)))) x Idea: Introducir <INCREMENTO-A> y <F-A> como argumentos de entrada. Las anteriores funciones serán entonces casos particulares. LP 2000–2001 Cc Ia Introducción a Lisp 0.52 Abstracción de procedimientos x Función suma ;;; (SUMA A B S F) => El valor de ;;; f(a) + f(s(a)) + f(s(s(a)) + ;;; + ... + f(s(...(s(a))...)) ;;; hasta que s(s(...(s(a))...)) > b. ;;; > (suma 2 5 #’1+ #’cubo) ;;; 224 (defun suma (a b s f &optional (res 0)) (if (> a b) res (suma (funcall s a) b s f (+ (funcall f a) res)))) x Casos particulares: (defun suma-enteros-2 (a b) (suma a b #’1+ #’identity)) (defun suma-cubos-2 (a b) (suma a b #’1+ #’cubo)) (defun suma-cubos-pares-2 (a b) (suma a b #’(lambda (x) (+ x 2)) #’cubo)) LP 2000–2001 Cc Ia Introducción a Lisp 0.53 Abstracción de procedimientos x Integral definida ;;; (INTEGRAL A B F H) ;;; Aproximación numérica de la integral de f entre ;;; a y b: ;;; (f(a+h/2) + f(a+h+h/2) + f(a+2h+h/2) + ... )h ;;; > (integral 0 1 #’cubo 0.01) ;;; 0.2399875 (defun integral (a b f h) (* (suma (+ a (/ h 2)) b #’(lambda (x) (+ x h)) f) h)) ;;; Más ejemplos: integral entre 0 y 1 de las ;;; siguientes funciones: ;;; (1) f(x) = x^4 ;;; (2) g(x) = 3x^2 + 4x^3 ;;; ;;; ;;; ;;; ;;; ;;; > (integral 0 1 #’(lambda (x) (* x x x x)) 0.01) 0.1999833 > (integral 0 1 #’(lambda (x) (+ (* 3 x x)( * 4 x x x))) 0.01) 1.999925 LP 2000–2001 Cc Ia Introducción a Lisp 0.54 Abstracción de procedimientos x Producto ;;; (PRODUCTO A B S F) => ;;; El valor de ;;; f(a) * f(s(a)) * f(s(s(a)) ;;; * ... * f(s(...(s(a))...)) ;;; hasta que s(s(...(s(a))...)) > b. ;;; > (producto 2 5 #’1+ #’(lambda (x) x)) ;;; 120 (defun producto (a b s f &optional (res 1)) (if (> a b) res (producto (funcall s a) b s f (* (funcall f a) res)))) ;;; (FACTORIAL N) => ;;; > (factorial 4) ;;; 24 El factorial de n. (defun factorial (n) (producto 1 n #’1+ #’identity)) LP 2000–2001 Cc Ia Introducción a Lisp 0.55 Abstracción de procedimientos x Idea: suma y producto pueden ser abstraidos u Basta con definir como parámetros cómo se acumula y el valor inicial de acumulador u La función ACUMULAR: ;;; (ACUMULAR A ;;; > (acumular ;;; 10 ;;; > (acumular ;;; 24 (defun acumular B S F COMBINAR VALOR-INICIAL) 1 4 #’1+ #’identity #’+ 0) 1 4 #’1+ #’identity #’* 1) (a b s f combinar valor-inicial &optional (res valor-inicial)) (if (> a b) res (acumular (funcall s a) b s f combinar valor-inicial (funcall combinar res (funcall f a))))) u Redefinición de suma y producto (defun suma-2 (a b s f) (acumular a b s f #’+ 0)) (defun producto-2 (a b s f) (acumular a b s f #’* 1)) LP 2000–2001 Cc Ia Introducción a Lisp 0.56 Programación aplicativa: b. d. libros x x Ejemplo: base de datos de libros u Vamos a representar una base de datos de libros u De cada libro: autor, tı́tulo y clasificación Creación: ;;; (CREA-LIBRO AUTOR TITULO CLASIFICACION) ;;; > (crea-libro ’((Patric Henry Winston) ;;; (Artificial Intelligence) ;;; (Tecnico IA))) ;;; ((AUTOR (PATRIC HENRY WINSTON)) ;;; (TITULO (ARTIFICIAL INTELLIGENCE)) ;;; (CLASIFICACION (TECNICO IA))) ;;; ;;; > (setf *libro-1* ;;; (crea-libro ;;; ’(Patric Henry Winston) ;;; ’(Artificial Intelligence) ;;; ’(Tecnico IA))) (defun crea-libro (autor titulo clasificacion) (list (list ’autor autor) (list ’titulo titulo) (list ’clasificacion clasificacion))) LP 2000–2001 Cc Ia Introducción a Lisp 0.57 Programación aplicativa: b. d. libros x Listas de asociación: la función ASSOC (ASSOC CLAVE LISTA-ASOCIACION) > (assoc ’a ’((c d e) (a b) (b d))) (A B) > (assoc ’a ’((c d e) (a b) (b d) (a c))) (A B) > (assoc ’a ’((c d e) (b d))) NIL x Acceso: ;;; (AUTOR LIBRO) ;;; > (autor *libro-1*) ;;; (PATRIC HENRY WINSTON) (defun autor (libro) (second (assoc ’autor libro))) ;;; (TITULO LIBRO) ;;; > (titulo *libro-1*) ;;; (ARTIFICIAL INTELLIGENCE) (defun titulo (libro) (second (assoc ’titulo libro))) ;;; (CLASIFICACION LIBRO) ;;; > (clasificacion *libro-1*) ;;; (TECNICO IA) (defun clasificacion (libro) (second (assoc ’clasificacion libro))) LP 2000–2001 Cc Ia Introducción a Lisp 0.58 Programación aplicativa: b. d. libros x Actualizaciones ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; ;;; (ACTUALIZA-AUTOR LIBRO AUTOR) > (setf *libro-1* (actualiza-autor *libro-1* ’(P. H. Winston))) ((AUTOR (P. H. WINSTON)) (TITULO (ARTIFICIAL INTELLIGENCE)) (CLASIFICACION (TECNICO IA))) > *libro-1* ((AUTOR (P. H. WINSTON)) (TITULO (ARTIFICIAL INTELLIGENCE)) (CLASIFICACION (TECNICO IA))) (defun actualiza-autor (libro autor) (crea-libro autor (titulo libro) (clasificacion libro))) ;;; (ACTUALIZA-TITULO LIBRO AUTOR) (defun actualiza-titulo (libro titulo) (crea-libro (autor libro) titulo (clasificacion libro))) ;;; (ACTUALIZA-CLASIFICACION LIBRO AUTOR) (defun actualiza-clasificacion (libro clasificacion) (crea-libro (autor libro) (titulo libro) clasificacion)) LP 2000–2001 Cc Ia Introducción a Lisp 0.59 Programación aplicativa: b. d. libros x Ejemplo de base de datos (setf *base-de-libros* (list (crea-libro ’(H. Farreny) ’(Ejercicios programados de inteligencia artificial) ’(IA Ejercicios)) (crea-libro ’(P.R. Tanimoto) ’(The elements of artificial intelligence) ’(IA Lisp)) (crea-libro ’(H. Wertz) ’(Lisp (Una introduccion a la programacion)) ’(Lisp)) (crea-libro ’(P.H. Winston) ’(Artificial Intelligence) ’(IA)))) x Preguntas a la base de datos LP 2000–2001 Cc Ia Introducción a Lisp 0.60 Programación aplicativa x Autores de la base de datos, versión recursiva (defun autores-rec (libros &optional autores) (if (endp libros) (reverse autores) (autores-rec (rest libros) (cons (autor (first libros)) autores)))) x La función MAPCAR (MAPCAR PROCEDIMIENTO LISTA) > (mapcar #’atom ’(a (b) 3)) (T NIL T) > (mapcar #’cuadrado ’(3 5 9)) (9 25 81) Generalización: (MAPCAR PROCEDIMIENTO LISTA-1 ... LISTA-N) > (mapcar #’+ ’(1 2 3) ’(4 5) ’(6 7 8)) (11 14) x Autores de la base de datos, versión aplicativa ;;; (AUTORES-APL LIBROS) ;;; > (autores-apl *base-de-libros*) ;;; ((H. FARRENY) (P.R. TANIMOTO) ;;; (H. WERTZ) (P.H. WINSTON)) (defun autores-apl (libros) (mapcar #’autor libros)) LP 2000–2001 Cc Ia Introducción a Lisp 0.61 Programación aplicativa x Libros de IA, versión recursiva (defun ia-p (libro) (member ’ia (clasificacion libro))) (defun libros-de-ia-rec (libros &optional res) (cond ((endp libros) (reverse res)) ((ia-p (first libros)) (libros-de-ia-rec (rest libros) (cons (first libros) res))) (t (libros-de-ia-rec (rest libros) res)))) x Las funciones REMOVE-IF, REMOVE-IF-NOT: (REMOVE-IF-NOT PROCEDIMIENTO LISTA) (REMOVE-IF PROCEDIMIENTO LISTA) > (remove-if-not #’atom ’((a) b (c) d)) (B C) > (remove-if #’atom ’((a) b (c) d)) ((A) (C)) x Libros de IA, versión aplicativa (defun libros-de-ia-apl (libros) (remove-if-not #’ia-p *base-de-libros*)) LP 2000–2001 Cc Ia Introducción a Lisp 0.62 Programación aplicativa x Libros de una materia, versión recursiva (defun libros-de-rec (materia libros &optional res) (cond ((endp libros) (reverse res)) ((member materia (clasificacion (first libros))) (libros-de-rec materia (rest libros) (cons (first libros) res))) (t (libros-de-rec materia (rest libros) res)))) x Libros de una materia, versión aplicativa ;;; (LIBROS-DE-APL MATERIA LIBROS) ;;; > (libros-de-apl ’ejercicios *base-de-libros*) ;;; (((AUTOR (H. FARRENY)) ;;; (TITULO (EJERCICIOS PROGRAMADOS <...>)) ;;; (CLASIFICACION (IA EJERCICIOS)))) (defun libros-de-apl (materia libros) (remove-if-not #’(lambda (x) (member materia (clasificacion x))) libros)) LP 2000–2001 Cc Ia Introducción a Lisp 0.63 Programación aplicativa x Número de libros de una materia, versión recursiva (defun cuenta-libros-de-rec (materia libros &optional (res 0)) (cond ((endp libros) res) ((member materia (clasificacion (first libros))) (cuenta-libros-de-ia-rec (rest libros) (+ 1 res))) (t (cuenta-libros-de-ia-rec (rest libros) res)))) x Las funciones COUNT-IF, COUNT-IF-NOT: (COUNT-IF PROCEDIMIENTO LISTA) (COUNT-IF-NOT PROCEDIMIENTO LISTA) > (count-if #’atom ’((a) b (c) d e)) 3 > (count-if-not #’atom ’((a) b (c) d e)) 2 x Número de libros de una materia, versión aplicativa (defun cuenta-libros-de-apl (materia libros) (count-if #’(lambda (x) (member materia (clasificacion x))) libros)) LP 2000–2001 Cc Ia Introducción a Lisp 0.64 Programación aplicativa x Un libro de una materia, versión recursiva (defun el-primer-libro-de-rec (materia libros) (cond ((endp libros) nil) ((member materia (clasificacion (first libros))) (first libros)) (t (el-primer-libro-de-rec materia (rest libros))))) x Las funciónes FIND-IF, FIND-IF-NOT: (FIND-IF PROCEDIMIENTO LISTA) (FIND-IF-NOT PROCEDIMIENTO LISTA) > (find-if #’atom ’((a) b (c) d e)) B > (find-if-not #’atom ’((a) b (c) d e)) (A) x Un libro de una materia, versión aplicativa (defun el-primer-libro-de-apl (materia libros) (find-if #’(lambda (x) (member materia (clasificacion x))) libros)) LP 2000–2001 Cc Ia Introducción a Lisp 0.65 Programación aplicativa x Todas las materias, versión recursiva (defun materias-rec (libros &optional res) (if (endp libros) res (materias-rec (rest libros) (union (clasificacion (first libros)) res)))) x Todas las materias, versión aplicativa (defun materias-apl (libros) (remove-duplicates (apply #’append (mapcar #’clasificacion libros)))) x Auxiliares: UNION, REMOVE-DUPLICATES: (UNION CONJUNTO-1 CONJUNTO-2) > (union ’(a (D A B C) > (union ’(a (D (B) A (B) > (union ’(a (D A (B) C) b c) ’(b c d)) (b) c) ’((b) c d)) C) (b) c) ’((b) c d) :test #’equal) (REMOVE-DUPLICATES LISTA) > (remove-duplicates ’(A B B C C D E)) (A B C D E) LP 2000–2001 Cc Ia Introducción a Lisp 0.66 Programación aplicativa x ¿Son todos de una materia dada?, versión recursiva (defun todos-son-de-rec (materia libros) (if (endp libros) t (and (member materia (clasificacion (first libros))) (todos-son-de-rec materia (rest libros))))) x La función EVERY: (EVERY PREDICADO LISTA) > (every #’atom ’(1 a)) > (every #’atom ’((1) a)) => T => NIL (EVERY PREDICADO LISTA-1 ... LISTA-N) > (every #’<= ’(1 2) ’(1 3)) > (every #’< ’(1 2) ’(1 3)) x => T => NIL ¿Son todos de una materia dada?, versión aplicativa (defun todos-son-de-apl (materia libros) (every #’(lambda (x) (member materia (clasificacion x))) libros)) LP 2000–2001 Cc Ia Introducción a Lisp 0.67 Programación aplicativa x ¿Hay alguno de una materia dada?, versión recursiva (defun algunos-son-de-rec (materia libros) (if (endp libros) nil (or (member materia (clasificacion (first libros))) (algunos-son-de-rec materia (rest libros))))) x Las funciónes SOME: (SOME PREDICADO LISTA) > (some #’atom ’((1) a)) > (some #’atom ’((1) (a))) => T => NIL (SOME PREDICADO LISTA-1 ... LISTA-N) > (some #’< ’(1 2) ’(1 3)) > (some #’< ’(1 2) ’(1 0)) x => T => NIL ¿Hay alguno de una materia dada?, versión aplicativa (defun algunos-son-de-apl (materia libros) (some #’(lambda (x) (member materia (clasificacion x))) libros)) LP 2000–2001 Cc Ia Introducción a Lisp 0.68 Estructuras x Ejemplo: > (defstruct persona (nombre nil) (estado ’casado) (calle nil) (ciudad ’Sevilla)) PERSONA > (setf ejemplo-1 (make-persona :nombre ’ana :calle ’(Reina Mercedes))) #S(PERSONA :NOMBRE ANA :ESTADO CASADO :CALLE (REINA MERCEDES) :CIUDAD SEVILLA) > (setf ejemplo-2 (make-persona :nombre ’pepe :ciudad ’Huelva)) #S(PERSONA :NOMBRE PEPE :ESTADO CASADO :CALLE NIL :CIUDAD HUELVA) > (persona-ciudad ejemplo-1) SEVILLA > (persona-nombre ejemplo-2) PEPE > (setf (persona-nombre ejemplo-1) ’(Ana Maria)) (ANA MARIA) > ejemplo-1 #S(PERSONA :NOMBRE (ANA MARIA) :ESTADO CASADO :CALLE (REINA MERCEDES) :CIUDAD SEVILLA) LP 2000–2001 Cc Ia Introducción a Lisp 0.69 Estructuras x Ejemplo (cont.): > (setf ejemplo-3 ejemplo-1) #S(PERSONA :NOMBRE (ANA MARIA) :ESTADO CASADO :CALLE (REINA MERCEDES) :CIUDAD SEVILLA) > (setf (persona-calle ejemplo-3) ’(tetuan)) (TETUAN) > ejemplo-3 #S(PERSONA :NOMBRE (ANA MARIA) :ESTADO CASADO :CALLE (TETUAN) :CIUDAD SEVILLA) > ejemplo-1 #S(PERSONA :NOMBRE (ANA MARIA) :ESTADO CASADO :CALLE (TETUAN) :CIUDAD SEVILLA) > (setf ejemplo-4 (copy-persona ejemplo-2)) #S(PERSONA :NOMBRE PEPE :ESTADO CASADO :CALLE NIL :CIUDAD HUELVA) > (setf (persona-ciudad ejemplo-4) ’cadiz) CADIZ > ejemplo-4 #S(PERSONA :NOMBRE PEPE :ESTADO CASADO :CALLE NIL :CIUDAD CADIZ) > ejemplo-2 #S(PERSONA :NOMBRE PEPE :ESTADO CASADO :CALLE NIL :CIUDAD HUELVA) LP 2000–2001 Cc Ia Introducción a Lisp 0.70 Estructuras x Creación de estructuras con defstruct: (DEFSTRUCT (NOMBRE (:CONSTRUCTOR F-CONSTRUCTURA) (:CONC-NAME PREFIJO-) (:PRINT-FUNCTION F-ESCRITURA)) CAMPO-1 ... CAMPO-N) x Ejemplo (puntos en el plano): (defstruct (punto (:constructor crea-punto) (:conc-name coordenada-) (:print-function escribe-punto) x y) x Ejemplo (función de escritura): (defun escribe-punto (punto &optional (canal t) profundidad) (format canal "Punto de abcisa ~a y ordenada ~a" (coordenada-x punto) (coordenada-y punto))) LP 2000–2001 Cc Ia Introducción a Lisp 0.71 Lisp: Estructuras x Ejemplo (cont.): > (setf *punto-1* (crea-punto :x 2 :y 3)) Punto de abcisa 2 y ordenada 3 > (coordenada-y *punto-1*) 3 > (setf (coordenada-y *punto-1*) 5) 5 > *punto-1* Punto de abcisa 2 y ordenada 5 > (punto-p *punto-1*) T > (punto-p ’(2 5)) NIL > (setf *punto-2* (copy-punto *punto-1*)) Punto de abcisa 2 y ordenada 5 > (equal *punto-1* *punto-2*) NIL > (equalp *punto-1* *punto-2*) T > (setf (coordenada-y *punto-2*) 3) 3 > *punto-2* Punto de abcisa 2 y ordenada 3 > (setf *punto-3* (crea-punto :y 3 :x 2)) Punto de abcisa 2 y ordenada 3 > (equalp *punto-2* *punto-3*) T LP 2000–2001 Cc Ia Introducción a Lisp 0.72 Bibliografı́a x Steele, G.L. Common Lisp the Language, 2nd edition (D. P., 1990). x Winston, P.R. y Horn, B.K. LISP (3a. ed.) (Addison–Wesley, 1991). x Paul Graham ANSI Common Lisp (PrenticeHall, 1996). x David B. Lamkins “Successful Lisp: How to Understand and Use Common Lisp” http://www.psg.com/~dlamkins/sl/cover.html LP 2000–2001 Cc Ia Introducción a Lisp 0.73