1990 Lisp
1990 Lisp
José A. Alonso
Dpto. de Álgebra, Computación, Geometrı́a y Topologı́a
Universidad de Sevilla
Sevilla, 1990
Contenido
1 El cálculo aritmético 1
1.1 Los números y sus operaciones . . . . . . . . . . . . . . . . . . 1
1.2 Nombrar los objetos de cálculo . . . . . . . . . . . . . . . . . . 4
1.3 Definición de nuevas funciones . . . . . . . . . . . . . . . . . . 6
1.4 Variables globales y locales . . . . . . . . . . . . . . . . . . . . 8
2 El cálculo simbólico 9
2.1 La función QUOTE sobre sı́mbolos . . . . . . . . . . . . . . . 9
2.2 Las expresiones en Lisp . . . . . . . . . . . . . . . . . . . . . . 10
2.3 La función QUOTE sobre listas . . . . . . . . . . . . . . . . . 11
2.4 Funciones de búsqueda en listas . . . . . . . . . . . . . . . . . 11
2.5 Funciones de construcción de listas . . . . . . . . . . . . . . . 16
2.6 Funciones de modificación fı́sica de listas . . . . . . . . . . . . 18
3 El control 19
3.1 Los valores lógicos . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Funciones de comparación de números . . . . . . . . . . . . . 19
3.3 Funciones de comparación de sı́mbolos y listas . . . . . . . . . 20
3.4 Condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.4.1 La función IF . . . . . . . . . . . . . . . . . . . . . . . 22
3.4.2 La función COND . . . . . . . . . . . . . . . . . . . . 23
3.4.3 Las funciones AND y OR . . . . . . . . . . . . . . . . 26
3.4.4 Las funciones WHEN y UNLESS . . . . . . . . . . . . 27
4 La programación recursiva 28
4.1 Funciones recursivas . . . . . . . . . . . . . . . . . . . . . . . 28
4.2 Las funciones TRACE y UNTRACE . . . . . . . . . . . . . . 29
4.3 Aritmética entera positiva . . . . . . . . . . . . . . . . . . . . 29
4.4 La aritmética ordinaria del lisp . . . . . . . . . . . . . . . . . 35
4.5 Simulación de primitivas sobre listas . . . . . . . . . . . . . . 36
4.6 Definición de funciones sobre listas . . . . . . . . . . . . . . . 39
i
4.7 Funciones sobre árboles . . . . . . . . . . . . . . . . . . . . . . 43
4.8 Funciones sobre conjuntos . . . . . . . . . . . . . . . . . . . . 44
5 La iteración en Lisp 47
5.1 El grupo PROG, GO, RETURN . . . . . . . . . . . . . . . . . 47
5.2 Las funciones DO y DO* . . . . . . . . . . . . . . . . . . . . . 51
5.3 Las funciones DOTIMES y DOLIST . . . . . . . . . . . . . . 53
5.4 La función MAPCAR . . . . . . . . . . . . . . . . . . . . . . . 56
6 Funciones anónimas 58
6.1 La función LAMBDA . . . . . . . . . . . . . . . . . . . . . . . 58
6.2 Las funciones EVERY y SOME . . . . . . . . . . . . . . . . . 59
9 Lectura y escritura 81
9.1 Funciones de lectura y escritura . . . . . . . . . . . . . . . . . 81
9.2 Funciones de lectura y escritura sobre ficheros . . . . . . . . . 86
Bibliografı́a 94
ii
Capı́tulo 1
El cálculo aritmético
5
*
1.1.2 Nota: El valor de un número es dicho número.
1.1.3 Ejemplo: Segunda sesión Lisp:
* (* 3 5) ; multiplica 3 por 5
15
* (* 2 3 4) ; multiplica 2 por 3 y por 4
24
* (/ 20 5) ; 20 dividido por 5
4.0
* (/ 5 20)
0.25
* (/ 24 3 2) ; (24/3) /2
4.0
* (/ 0.5) ; 1/0.5
2.0
1.1.4 Notas:
1. Los números pueden combinarse entre sı́ mediante operaciones aritméticas
usando la notación prefija.
1
2. Para escribir un comentario se utiliza ; y el resto de la lı́nea es ignorado
por el intérprete.
* (* (- 1 2) (+ 4 5))
-9
* (+ (+ 15 5) (- 100 45))
75
1.1.6 Notas:
2(4 − 1)6
+ (8 − 6)7
18
Solución:
* (+ (* 2 (- 4 1) (/ 6 18)) (* (- 8 6) 7))
16.0
* (+ (* 2
(- 4 1)
(/ 6 18))
(* (- 8 6)
7))
16.0
1.1.8 Notas:
2
* (EXIT)
C>
1.1.10 Nota: Para entrar al LISP pulsar GCLISP, y para salir (EXIT).
1.1.11 Definición: Funciones numéricas:
(+ n1 n2 ... nN) devuelve el valor de la suma n1+n2+...+nN . Si N = 0,
da 0.
(+) ---> 0
(+ 3) ---> 3
(+ 3 7 5) ---> 15
(+ 32000 32000) ---> ERROR
(+ 32000.0 32000) ---> 64000.0
(- 3) ---> -3
(- 123 7 5) ---> 111
(ABS 3) ---> 3
(ABS -3.6) ---> 3.6
(*) ---> 1
(* 3) ---> 3
(* 3 7 5) ---> 105
(* 32000 32000) ---> ERROR
(* 32000.0 32000) ---> 1.024F+09
3
(/ 6 2) ---> 3.0
(/ 5 2) ---> 2.5
(/ 2) ---> 0.5
(/ 0.5) ---> 2.0
(MOD 7 2) ---> 1
(MAX 3) ---> 3
(MAX 1 2 3 4 5 2) ---> 5
(MAX -2.3 7 0) ---> 7.0
(MIN 3) ---> 3
(MIN 1 2 3 4 5 2) ---> 1
(MIN -2.3 7 0) ---> -2.3
4
80
* (/ (* PRECIO IVA) 100)
8.O
* (+ 1 2 X 3)
ERROR:
Unbound variable: X
1> <Control C>
Top-Level
* (SETQ X (* 2 5))
10
* (+ 1 2 X 3 )
16
* (SETQ X 1 Y 2 Z (+ X Y))
3
* (+ X Y Z)
6
1.2.2 Definición: La función SETQ:
(SETQ SIMB-1 EXP-1 ... SIMB-N EXP-N) asigna al sı́mbolo SIMB-
1 el valor de la expresión EXP-1,..., a SIMB-N el valor de EXP-N y
devuelve el valor de EXP-N.
1.2.3 Nota: La función SETQ modifica el entorno de cálculo.
1.2.4 Ejercicio: Calcular el valor de C después de la evaluación de la
expresión
(SETQ A 3 C (+ (SETQ B 4) (+ A B)))
Solución: 11.
1.2.5 Definición: Las funciones INCF y DECF:
(INCF s n) = (SETQ s (+ s n)).
(INCF s) = (INCF s 1).
(DECF s n) = (SETQ s (- s n)).
(DECF s) = (DECF s 1).
1.2.6 Ejemplo:
(SETQ X 3) ---> 3
(INCF X) ---> 4
X ---> 4
(DECF X 3) ---> 1
X ---> 1
5
1.3 Definición de nuevas funciones
1.3.1 Ejemplo: Definición de la función CUBO:
* (DEFUN SUMA-BINARIA (X Y)
(+ X Y))
SUMA-BINARIA
* (SUMA-BINARIA 2 3)
5
* (SETQ X -1)
-1
* (SUMA-BINARIA 2 3)
5
* X
-1
* (+ (SUMA-BINARIA 2 3) X)
4
* (* (SUMA-BINARIA (+ 50 50) 1) 3)
303
1.3.4 Ejercicio: Escribir una función P2 que calcule el valor del polinomio
ax2 + bx + c. Por ejemplo,
(P2 4 3 2 2) ---> 24
Solución:
(DEFUN P2 (A B C X)
(+ (* A X X) (* B X) C))
1.3.5 Nota: La lista de parámetros de una función puede ser vacı́a. Por
ejemplo,
6
* (DEFUN NUMERO ()
(SETQ X (1+ X)))
NUMERO
* (SETQ X 0) ; INICIALIZA X
0
* (+ (NUMERO) (NUMERO) (NUMERO)) ; (+ 1 2 3)
6
* X
3
1.3.6 Nota: La función NUMERO tiene “efecto de borde” porque altera
el entorno de cálculo. Al escribir funciones conviene evitar efectos de borde.
1.3.7 Nota: Un problema puede resolverse de forma “descendente” (de-
scomponiéndolo en otros más simples) o de forma “ascendente” (desarrollar
utilidades y combinarlas). Se aconseja la forma descendente.
1.3.8 Ejemplo: (de programación descendente) Definir la función
(MEDIA-CUADRADO X Y)
que devuelva la media de los cuadrados de X e Y.
* (DEFUN MEDIA-CUADRADO (X Y)
(MEDIA (CUADRADO X) (CUADRADO Y)))
MEDIA-CUADRADO
* (DEFUN CUADRADO (X)
(* X X))
CUADRADO
* (CUADRADO 3) ; TEST DE CUADRADO
9
* (DEFUN MEDIA (X Y)
(/ (+ X Y) 2))
MEDIA
* (MEDIA 4 8) ; TEST DE MEDIA
6.0
* (MEDIA-CUADRADO 2 4)
10.0
1.3.9 Ejercicio: Definir CUADRADO-MEDIA tal que (CUADRADO-
MEDIA X Y) sea el cuadrado de la media de X e Y. Por ejemplo,
(CUADRADO-MEDIA 2 4) ---> 9.0
Solución:
(DEFUN CUADRADO-MEDIA (X Y)
(CUADRADO (MEDIA X Y)))
7
1.4 Variables globales y locales
1.4.1 Definición: La función LET:
(LET ((VAR1 VAL1) ... (VARN VALN)) S1 ...SM) asocia a la vari-
able VAR1 el valor VAL1,..., a la variable VARN el valor VALN, calcula
las expresiones S1,..., SM, reconstruye el entorno y devuelve el valor de
SM.
1.4.2 Ejemplo:
(SETQ X 1) ---> 1
(LET ((X 2) (Y 3)) (+ X Y)) ---> 5
X ---> 1
1.4.3 Ejercicio: Definir una función F1 que calcule la media de los cuadra-
dos de las raı́ces de la ecuación ax2 + bx + c = 0. Por ejemplo,
(F1 1 -5 6) ---> 6.5
Solución:
(DEFUN F1 (A B C)
(LET ((AUX1 (- B))
(AUX2 (SQRT (- (* B B)
(* 4 A C))))
(AUX3 (* 2 A)))
(MEDIA-CUADRADO (/ (+ AUX1 AUX2) AUX3)
(/ (- AUX1 AUX2) AUX3))))
1.4.4 Nota: Una función puede tener el mismo nombre que una variable.
1.4.5 Ejemplo:
* (SETQ DOS 2)
2
* (DEFUN DOS () ; UNA FUNCION QUE DEVUELVE 3.
3)
DOS
* (+ DOS (DOS))
5
1.4.6 Ejercicio: Escribir una función P4 que calcule el valor del polinomio
3x4 + 7x2 + 4 utilizando la función P2.
Solución:
(DEFUN P4 (X)
(P2 3 7 4 (* X X)))
8
Capı́tulo 2
El cálculo simbólico
ERROR:
Unbound variable: A
1> <Control C>
Top-Level
* (SETQ A 3)
3
* (QUOTE A)
A
* ’A
A
2.1.3 Ejemplo: De uso de QUOTE y SETQ:
(SETQ HOMBRE ’SOCRATES) ---> SOCRATES
HOMBRE ---> SOCRATES
(SETQ SOCRATES 1) ---> 1
HOMBRE ---> SOCRATES
(SETQ MORTAL HOMBRE) ---> SOCRATES
MORTAL ---> SOCRATES
9
2.1.4 Definición: La función SET:
2.1.6 Nota: (SETQ SIMB EXP) es lo mismo que (SET ’SIMB EXP)
Solución:
10
LISTA NUMERO DE SEGUNDO
ELEMENTOS ELEMENTO
(1 DOS 3 CUATRO) 4 DOS
(SOCRATES (- 43 1)) 2 (- 43 1)
((X 1) (Y 2) (Z 3)) 3 (Y 2)
(- (* 2 (+ A 3))) 2 (* 2 (+ A 3))
(((1))) 1 < NO TIENE >
(DEFUN SUMA (X Y) (+ X Y)) 4 SUMA
() 0 < NO TIENE >
2.2.8 Nota: Hay átomos constantes como T, que representa el valor ver-
dadero y NIL, que representa el valor falso.
2.3.2 Ejemplo:
(A B C) ---> ERROR:
Undefined function: A
while evaluating: (A B C)
1> <Control C>
(QUOTE (A B C)) ---> (A B C)
’(A B C) ---> (A B C)
(+ 2 3) ---> 5
’(+ 2 3) ---> (+ 2 3)
11
(CAR L) devuelve el primer elemento de L, si L es una lista no vacı́a y
NIL, en otro caso.
2.4.1.2 Ejemplo:
Solución:
2.4.1.5 Ejemplo:
12
2.4.1.6 Nota: Una forma de representar las listas es mediante un árbol cuya
raı́z es el sı́mbolo “.”, su hijo izquierdo es el CAR, su hijo derecho es el CDR
y sus hojas son átomos. Por ejemplo,
A NIL
A .
B NIL
. NIL
A NIL
((A B) C (D E))
(DEFUN SUMA (X Y) (+ X Y))
13
(NTH N L) devuelve el N-ésimo elemento de L, empezando a contar
por 0.
(NTHCDR N L) devuelve el N-ésimo CDR de L, empezando a con-
tar por 0.
(LAST L) devuelve la lista formada por el último elemento de L.
(LENGTH L) devuelve el número de elementos de L.
2.4.1.10 Ejemplo:
14
Solución:
Solución:
Solución:
Por ejemplo,
15
(NOMBRE 1) ---> PEPE
(DIRECCION 2) ---> CUNA-5
(TELEFONO 3) ---> "456345"
Solución:
2.4.2.2 Ejemplo:
(LIST EXP1 ... EXPN) devuelve una lista cuyos elementos son los
valores de las expresiones EXP1, ..., EXPN.
16
2.4.2.5 Ejemplo:
2.4.2.7 Ejemplo:
Solución:
17
Solución:
2.4.3.3 Ejemplo:
(POP SIMB) (SIMB tiene que ser un sı́mbolo cuyo valor sea una
lista). La función devuelve el CAR de esta lista y asocia a SIMB
el CDR de su antiguo valor.
2.4.3.5 Ejemplo:
18
Capı́tulo 3
El control
19
(/= 10 (+ 3 7)) ---> NIL
(/= 2 2.0 (+ 1 1)) ---> NIL
(/= 1 2 3) ---> T
(/= 1 2 1) ---> NIL
(>= n1 ... nN)+ devuelve T si n1 >= ... >= nN; NIL, en otro caso.
(>= 4 3 3 2) ---> T
(>= 4 3 3 5) ---> NIL
(> n1 ... nN)+ devuelve T si n1 > ... > nN; NIL, en otro caso.
(> 4 3 2 1) ---> T
(> 4 3 3 2) ---> NIL
(<= n1 ... nN)+ devuelve T si n1 <= ... <= nN; NIL, en otro caso.
(<= 2 3 3 4) ---> T
(<= 5 3 3 4) ---> NIL
(< n1 ... nN)+ devuelve T si n1 < ... < nN; NIL, en otro caso.
(< 1 2 3 4) ---> T
(< 1 3 3 4) ---> NIL
20
3.3.2 Ejemplo:
3.3.4 Ejemplo:
3.3.6 Ejemplo:
21
(NUMBERP S) devuelve T, si S es un número y NIL, en otro caso.
(CONSP S) devuelve T, si S es una lista no vacı́a y NIL, en otro caso.
(LISTP S) devuelve T, si S es una lista y NIL, en otro caso.
3.3.8 Ejemplo:
3.4 Condicionales
3.4.1 La función IF
3.4.1.1 Definición: La función IF:
(IF S S1 S2) Si el valor de S es verdadero (i.e. una expresión distinta
de NIL), devuelve el valor de S1. Si el valor de S es NIL, devuelve
el valor de S2.
(IF T 1 2) ---> 1
(IF NIL 1 2) ---> 2
(IF (= (SETQ A 3) 4) 1 0) ---> 0
(IF (= A 3) 1 0) ---> 1
(IF (= A 4) (+ A 2)) ---> NIL
(IF (/ A 4) (- A 2)) ---> 1
22
3.4.1.2 Ejercicio: Definir la función ABSOLUTO que devuelva el
valor absoluto de un número (i.e. el número sin el signo). Por ejemplo,
Solución:
23
| SUSPENSO , si N < 5
| APROBADO , si 5 <= N < 7
(NOTA N) = | NOTABLE , si 7 <= N < 9
| SOBRESALIENTE, si 9 <= N <= 10
| ERROR , si N > 10
Solución:
24
* U
VAL2
* Y
NIL
* (COND (( = (+ 2 3) 6) ’UNO)
(’DOS))
DOS
* (COND ((ATOM ’(A)) ’UNO)
((LISTP ’A) ’DOS))
NIL
25
Definir una función AYUDA-QUIMICA tal que al leer una expresión S
devuelva:
– Una lista de la forma (METAL DE DENSIDAD N), si S es un metal
de la lista METALES y N es la densidad de S.
– GAS-NOBLE, si S está en la lista GASES-NOBLES.
– DESCONOCIDO, en otro caso.
Por ejemplo:
Solución:
(AND (SETQ L ’(A B)) (SETQ M (CDDR L)) (SETQ L ’(X))) ---> NIL
M ---> NIL
L ---> (A B)
(EMPIEZA-POR-NUMERO S)
26
(EMPIEZA-POR-NUMERO ’(1 A)) ---> T
(EMPIEZA-POR-NUMERO T) ---> NIL
Solución:
(OR S1 ... SN) evalúa sucesivamente S1, ..., SN hasta que una no
vale NIL o no quedan más. En el primer caso devuelve el primer
valor no NIL encontrado y en el segundo, devuelve NIL. Ejemplos:
27
Capı́tulo 4
La programación recursiva
Por tanto,
En general,
28
El cálculo de (FACT 3) se realiza como sigue:
* (TRACE FACT)
(FACT)
* (FACT 3)
Entering: FACT, Argument list: (3)
Entering: FACT, Argument list: (2)
Entering: FACT, Argument list: (1)
Exiting: FACT, Value: 1
Exiting: FACT, Value: 2
Exiting: FACT, Value: 6
6
* (UNTRACE)
(FACT)
29
y predicados sobre los números enteros positivos usando solamente las
funciones 1+, 1- y el predicado =.
4.3.2 Ejercicio: Definir las funciones SUC y PRED tales que
(SUC N) = N + 1
(PRED N) = N - 1
Solución:
Solución:
(MENOR-P 0 3) ---> T
(MENOR-P 3 3) ---> NIL
Solución:
30
El cálculo de (MENOR-P 3 5) se realiza como sigue:
(MENOR-P 3 5) = (MENOR-P 2 4) =
= (MENOR-P 1 3) =
= (MENOR-P 0 2) =
= T
(SUMA N1 N2) = N1 + N2
Solución:
Usando el primer esquema:
(SUMA 2 3) = (SUMA 1 4) =
= (SUMA 0 5) =
= 5
31
(SUMA 2 3) = (SUC (SUMA 1 3)) =
= (SUC (SUC (SUMA 0 3))) =
= (SUC (SUC 3)) =
= (SUC 4) =
= 5
(PRODUCTO N1 N2) = N1 * N2
32
usando las funciones definidas en este parágrafo.
Solución: Por recursión sobre N1:
½
0 si N1 = 0
N1 * N2 =
(N1 - 1) * N2 + N2 en otro caso
33
Por ejemplo, para calcular (PAR-P 3),
(PAR-P 1 3 ) = (IMPAR-P 1 2) = (PAR-P 1 1) = (IMPAR-P 1 0) = NIL
4.3.11 Ejercicio: Definir la función COCIENTE tal que
(COCIENTE N1 N2) = Parte entera de N1/N2
Por ejemplo:
(COCIENTE 7 2) = 3
Solución:
½
0 si N1 < N2
COCIENTE (N1, N2) =
COCIENTE (N1 - N2, N2) + 1 en otro caso
(DEFUN COCIENTE (N1 N2)
(COND ((MENOR-P N1 N2) 0)
(T (SUC (COCIENTE (RESTA N1 N2) N2))) ))
4.3.12 Ejercicio: Definir la función RESTO tal que
(RESTO N1 N2) = Resto de dividir N1 entre N2.
Por ejemplo,
(RESTO 7 2) ---> 1
Solución:
½
N1 si N1 < N2
RESTO (N1, N2) =
RESTO (N1 - N2, N2) en otro caso
(DEFUN RESTO (N1 N2)
(COND ((MENOR-P N1 N2) N1)
(T (RESTO (RESTA N1 N2) N2)) ))
4.3.13 Ejercicio: Definir la función DIVISION tal que (DIVISION
N1 N2) sea una lista cuyo primer elemento sea la parte entera de N1/N2
y el segundo, el resto de dividir N1 entre N2. Por ejemplo,
(DIVISION 7 2) ---> (3 1)
Solución:
(DEFUN DIVISION (N1 N2)
(COND ((MENOR-P N1 N2) (LIST 0 N1))
(T (LET ((DIV (DIVISION (RESTA N1 N2) N2)))
(LIST (SUC (CAR DIV)) (CADR DIV)) ))))
34
4.4 La aritmética ordinaria del lisp
4.4.1 Ejercicio: Definir la función POTENCIA tal que
INDET si N1 = N2 = 0
0 si N1 = 0 y N2 6= 0
(POTENCIA N1 N2) =
1 si N1 6= 0 y N2 = 0
N2
N1 en otro caso
Por ejemplo,
(POTENCIA 2 3) ---> 8
N1^N2 = N1 * N1^(N2 - 1)
35
4.5 Simulación de primitivas sobre listas
4.5.1 Ejercicio: Redefinir la función LENGTH (llamarle N-LENGTH).
Solución:
Por ejemplo,
(DEFUN N-NTH (N L)
(COND ((NULL L) ())
((= N 0) (CAR L))
(T (N-NTH (1- N) (CDR L))) ))
Por ejemplo,
36
(DEFUN N-APPEND (L1 L2)
(COND ((NULL L1) L2)
(T (CONS (CAR L1) (N-APPEND (CDR L1) L2))) ))
Por ejemplo,
Solución:
(DEFUN N-MEMBER (E L)
(COND ((NULL L) ())
((EQUAL E (CAR L)) L)
(T (N-MEMBER E (CDR L))) ))
Por ejemplo,
37
Por ejemplo,
(DEFUN N-REMOVE (S L)
(COND ((NULL L) ())
((EQUAL S (CAR L)) (REMOVE S (CDR L)))
(T (CONS (CAR L)
(N-REMOVE S (CDR L)) ))))
38
4.6 Definición de funciones sobre listas
4.6.1 Ejercicio: Definir la función SUBSTOP que trabaje como
SUBST pero sólo en el primer nivel. Por ejemplo,
Solución:
Solución:
Solución:
39
4.6.4 Ejercicio: Definir la función CUENTA-ATOMOS que aplicada
a una lista, devuelve el número de átomos que contiene. Por ejemplo,
Solución:
Solución:
Solución:
40
(DEFUN MEM (E L) ; USANDO LINEALIZA
(IF (MEMBER E (LINEALIZA L)) T))
4.6.7 Ejercicio: Definir la función SEPARA que tome una lista (de
los niveles que sea) y separe las letras de los números. Por ejemplo,
Solución:
41
Solución:
Solución:
Solución:
42
4.7 Funciones sobre árboles
4.7.1 Nota: Los árboles pueden representarse por listas. Por ejemplo,
el árbol
A . . E
B C D .
Solución:
43
4.7.4 Ejercicio: Definir (N-ARCOS L) que devuelva el número de
arcos del árbol asociado a L. Por ejemplo,
Solución:
Solución:
Solución:
44
(DEFUN REDUCE-CONJUNTO (L)
(COND ((ATOM L) L)
((MEMBER (CAR L) (CDR L))
(REDUCE-CONJUNTO (CDR L)))
(T (CONS (REDUCE-CONJUNTO (CAR L))
(REDUCE-CONJUNTO (CDR L))))))
Solución:
Solución:
45
(DIF ’(0 3 6 9 12) ’(0 4 8 12)) ---> (3 6 9)
Solución:
Solución:
Solución:
46
Capı́tulo 5
La iteración en Lisp
47
5.1.4 Ejemplo: Redefinir la función factorial usando PROG.
Solución:
(POTENCIA2 M N) = M N
Solución:
(DEFUN POTENCIA (M N)
(PROG ((RESULTADO 1))
ETIQUETA
(SETQ RESULTADO (* M RESULTADO)
N (1- N))
(IF (= N 0) (RETURN RESULTADO))
(GO ETIQUETA)))
48
(DEFUN N-LENGTH (L)
(PROG ((AUX 0))
ETIQUETA
(IF (NULL L) (RETURN AUX))
(SETQ AUX (1+ AUX)
L (CDR L))
(GO ETIQUETA)))
Iteracion AUX L
0 0 (A B C)
1 1 (B C)
2 2 (C)
3 3 ()
4 3
(DEFUN N-NTHCDR (N L)
(PROG ()
ETIQUETA
(IF (= N 0) (RETURN L))
(SETQ N (1- N)
L (CDR L))
(GO ETIQUETA)))
(DEFUN N-MEMBER (S L)
(PROG ()
ETIQUETA
(COND ((NULL L) (RETURN NIL))
((EQUAL S (CAR L)) (RETURN L)))
(SETQ L (CDR L)) ; PUEDE SUSTITUIRSE POR (POP L)
(GO ETIQUETA)))
49
5.1.9 Ejercicio: Escribir la definición iterativa, usando PROG, de la
función REVERSE.
Solución:
Iteracion L AUX
0 (A B C) ()
1 (B C) (A)
2 (C) (B A)
3 () (C B A)
Iteracion L1 L2
0 (A B) (C D)
0 (B A) (C D)
1 (A) (B C D)
2 () (A B C D)
50
5.2 Las funciones DO y DO*
5.2.1 Definición: La estructura de la función DO es la siguiente:
Iteracion X N
0 (A B C) 0
1 (B C) 1
2 (C) 2
3 () 3
4 3
51
5.2.3 Ejercicio: Redefinir FACTORIAL usando DO.
Solución:
(POTENCIA M N) = M N
Solución:
52
(DEFUN POTENCIA (M N)
(DO ((RESULTADO 1 (* M RESULTADO))
(CONTADOR N (1- CONTADOR)))
((= CONTADOR 0) RESULTADO)))
Solución:
Solución:
53
(DO ((VAR 0 (1+ VAR)))
((= VAR M) RESULTADO)
S1 ... SN)
es decir; asigna a VAR el valor 0; evalúa S1,..., SN; aumenta el
valor de VAR en 1, si dicho valor es igual a M devuelve RESUL-
TADO; en otro caso, itera el proceso.
* (DOTIMES (CONTADOR 3 ’FIN)
(PRINT CONTADOR) )
0
1
2
FIN
5.3.2 Ejercicio: Redefinir FACT usando DOTIMES.
Solución:
(DEFUN POTENCIA (M N)
(LET ((RESULTADO 1))
(DOTIMES (CONTADOR N RESULTADO)
(SETQ RESULTADO (* RESULTADO M)) )))
54
(DOLIST (VAR L RESULTADO) S1...SN) es lo mismo que
(DO* ((LISTA-AUX L (CDR L))
(VAR (CAR LISTA-AUX) (CAR LISTA-AUX)) )
((NULL LISTA-AUX) RESULTADO)
S1 ... SN)
es decir; asigna a VAR el primer elemento de la lista L; evalúa
S1,..., SN; si L no tiene más elementos, devuelve RESULTADO;
en otro caso, le asigna a VAR el siguiente elemento de L e itera el
proceso.
* (DOLIST (CONTADOR ’(A B C) ’FIN)
(PRINT CONTADOR) )
A
B
C
FIN
(CUENTA-APROBADOS L)
Solución:
55
5.4 La función MAPCAR
5.4.1 Definición: La función MAPCAR:
56
(SUMA-VECTORES ’(3 5) ’(4 3)) ---> (7 8)
Solución:
Solución:
(PRODUCTO-ESCALAR ’(A1 ... AN) ’(B1 ...BN)) ---> A1.B1 +...+ AN.BN
Por ejemplo,
Solución:
Solución:
57
Capı́tulo 6
Funciones anónimas
Solución:
58
(DEFUN PARTES-DE (L)
(COND ((NULL L) (LIST NIL))
(T (APPEND (PARTES-DE (CDR L))
(MAPCAR #’(LAMBDA (X) (CONS (CAR L) X))
(PARTES-DE (CDR L)) )))))
6.2.2 Ejemplos:
Solución:
(DEFUN SUBCONJUNTO (A B)
(IF (EVERY #’(LAMBDA (X) (MEMBER X B)) A) T NIL))
59
(DEFUN SUBCONJUNTO (A B)
(IGUAL-CONJUNTO (UNION A B) B))
(DEFUN SUBCONJUNTO (A B)
(IGUAL-CONJUNTO (INTERSECCION A B) A))
(DEFUN DISJUNTOP (A B)
(IF (NOT (SOME #’(LAMBDA (X) (MEMBER X B))
A))
T
NIL))
(DEFUN DISJUNTOP (A B)
(NULL (INTERSECCION A B)))
60
Capı́tulo 7
7.1.3 Nota: Las listas son casos particulares de pares punteados. Por
ejemplo,
7.2 A–listas
7.2.1 Definición: Una A–lista (lista de asociación) es una lista de
pares punteados. Tiene la siguiente estructura:
61
((CLAVE-1 . VALOR-1) ... (CLAVE-N . VALOR-N))
62
(ASSOC SIMB AL) devuelve el elemento de la A–lista AL cuya
clave es SIMB. Por ejemplo,
(ASSOC ’B ’((A . 1) (B . 2) (C . 3)))) ---> (B . 2)
(ASSOC ’(B) ’((A . 1) ((B) 1) (C D))) ---> ((B) 1)
63
* (SETQ DICCIONARIO ’((2 . DOS)(4 . CUATRO)(+ . MAS)(= . IGUAL-A)))
((2 . DOS)(4 . CUATRO)(+ . MAS)(= . IGUAL-A))
* (SUBLIS DICCIONARIO ’(2 + 2 = 4))
(DOS MAS DOS IGUAL-A CUATRO)
NUMEROS = (1 2 3)
CASTELLANO = (UNO DOS TRES)
INGLES = (ONE TWO THREE)
FRANCES = (UN DEUX TROIS)
64
Solución:
(NOMBRE N I)
Solución:
(DEFUN NOMBRE (N I)
(COND ((EQUAL I ’CASTELLANO) (EN-CASTELLANO N))
((EQUAL I ’INGLES) (EN-INGLES N))
((EQUAL I ’FRANCES) (EN-FRANCES N))
(T ’ERROR) ))
65
Solución:
(VALOR N I)
Solución:
(DEFUN VALOR (N I)
(COND ((EQUAL I ’CASTELLANO) (VALOR-CASTELLANO N))
((EQUAL I ’INGLES) (VALOR-INGLES N))
((EQUAL I ’FRANCES) (VALOR-FRANCES N))
(T ’ERROR) ))
(FRANCES-A-CASTELLANO S)
Solución:
66
Capı́tulo 8
8.1 P–listas
8.1.1 Definición: Una P–lista (lista de propiedades) es una lista de
la forma
67
(SYMBOL-PLIST PL) devuelve la P–lista asociada a PL, si la hay
y NIL, si no. Por ejemplo, continuando con el anterior,
(SYMBOL-PLIST ’PEPE) ---> (EDAD 40 HIJOS (PEPITO PEPITA))
(SYMBOL-PLIST ’JUAN) ---> NIL
Solución:
68
(SETF (SYMBOL-PLIST ’JUAN) ’(EDAD 35 MUJER SOFIA HIJO TOMAS))
(SETF (SYMBOL-PLIST ’SOFIA) ’(EDAD 30 MARIDO JUAN HIJO TOMAS))
(SETF (SYMBOL-PLIST ’TOMAS) ’(EDAD 5 PADRE JUAN MADRE SOFIA))
Solución:
8.1.11 Ejercicio: Escribir una lista PADRES que contenga los padres
de árbol anterior.
Solución:
69
(SETQ PADRES ’(ARTURO PEPE ANTONIO ANICETO))
Solución:
(PADRE X) = Y <==>
<==> Y pertenece a PADRES y X es un hijo de Y
<==> Y pertenece a PADRES y X pertenece a (GET ’HIJOS-DE Y)
<==> Y pertenece a PADRES y (MEMBER X (GET ’HIJOS-DE Y))
<==> Y = (SOME ’(LAMBDA (Y) (IF (MEMBER X (GET ’HIJOS-DE Y)) Y))
PADRES)
(DEFUN PADRE (X)
(SOME #’(LAMBDA (Y) (IF (MEMBER X (GET ’HIJOS-DE Y)) Y))
PADRES))
X = GONZALO
PADRES = (ARTURO PEPE ANTONIO ANICETO)
Y = = ARTURO PEPE
(GET HIJOS-DE Y) = (JUAN) (GONZALO)
(MEMBER X (GET ’HIJOS-DE Y)) = NIL (GONZALO)
70
Iteracion AUX (MEMBER ’GONZALO (GET...)
1 (ARTURO PEPE ANTONIO ANICETO) NIL
2 (PEPE ANTONIO ANICETO) (GONZALO)
(DEFUN PADRE-AUX (X L)
(COND ((NULL L) NIL)
((MEMBER X (GET ’HIJOS-DE (CAR L))) (CAR L))
(T (PADRE-AUX X (CDR L)))))
(PADRE ’GONZALO) =
= (PADRE-AUX ’GONZALO ’(ARTURO PEPE ANTONIO ANICETO))
= (PADRE-AUX ’GONZALO ’(PEPE ANTONIO ANICETO))
= PEPE
Solución:
Solución:
71
(DEFUN DECANO (X)
(LET ((AUX (PADRE X)))
(COND ((NULL AUX) X)
(T (DECANO AUX)))))
Solución:
Por ejemplo,
(ANCESTROS ’GONZALO) =
= (CONS ’GONZALO (CONS ’PEPE (ANCESTROS ’ANICETO))) =
= (CONS ’GONZALO (CONS ’PEPE ’(ANICETO)) =
= (GONZALO PEPE ANICETO)
72
(HERMANOS ’PEPE) ---> (ANTONIO RODRIGO)
(HERMANOS ’JUAN) ---> NIL
Solución:
Por ejemplo,
(HERMANOS ’PEPE) =
= (REMOVE ’PEPE (GET ’HIJOS-DE (PADR ’PEPE))) =
= (REMOVE ’PEPE (GET ’HIJOS-DE ’ANICETO)) =
= (REMOVE ’PEPE ’(ANTONIO PEPE RODRIGO)) =
= (ANTONIO RODRIGO)
Solución:
73
Definir la función
(ADD-LIBRO ’LIBRO-2
"WINSTON Y HORN"
"LISP"
"ADDISON WESLEY") ---> LIBRO-2
LIBROS ---> (LIBRO-2 LIBRO-1)
(GET ’LIBRO-2 ’TITULO) ---> "LISP"
Solución:
Solución:
74
8.3 Programación dirigida por los datos
8.3.1 Definición: La función EVAL:
(CALCULAR ’A ’MAS B) = A + B
(CALCULAR ’(A B) ’MAS ’(C D) = (A + C B + D)
(CALCULAR ’A ’MENOS ’B) = A - B
(CALCULAR ’(A B) ’MENOS ’(C D) = (A - C B - D)
Por ejemplo,
Solución:
Por ejemplo,
75
(CALCULAR 2 ’MAS 3) =
= (EVAL (GET (IF (ATOM 2) ’REAL ’COMPLEJO) ’MAS)) =
= (EVAL (GET ’REAL ’MAS)) =
= (EVAL ’(+ 2 3)) =
= 5
Por ejemplo,
Solución:
Por ejemplo,
76
(FACTORIAL 4) =
= (SETF (GET ’FACTORIAL 4)
(* 4 (FACTORIAL 3))) =
= (SETF (GET ’FACTORIAL 4)
(* 4 (SETF (GET ’FACTORIAL 3)
(* 3 (FACTORIAL 2))))) =
= (SETF (GET ’FACTORIAL 4)
(* 4 (SETF (GET ’FACTORIAL 3)
(* 3 (* 2 (FACTORIAL 1)))))) =
= (SETF (GET ’FACTORIAL 4)
(* 4 (SETF (GET ’FACTORIAL 3)
6))) =
= 24
o, consultarla, mediante
(FACTORIAL 3) = 6
(FACTORIAL 5) =
= (SETF (GET ’FACTORIAL 5) (* 5 (FACTORIAL 4))) =
= (SETF (GET ’FACTORIAL 5) (* 5 24)) =
= 120
77
(TIME S) devuelve el tiempo empleado en calcular la expresión S.
Por ejemplo,
* (DEFUN FACT (N) (IF (= N 0) 1 (* N (FACT (1- N)))))
FACT
* (TIME (FACT 50.0))
Evaluating: (FACT 50.0)
Elapsed time: 0:00.11
6.80565F+38
8.4.4 Ejercicio: Comparar el tiempo empleado en calcular los facto-
riales de 100, 150 y 200 con las definiciones anteriores.
8.4.5 Ejercicio: La función de FIBONACCI está definida por
½
1 si N = 0 ó N = 1
FIB (N) =
FIB(N-1) + FIB(N-2) en otro caso
Los primeros términos de la sucesion son 1, 1, 2, 3, 5, 8, 13, 21,...
Escribir la función
(FIB N)
(FIB 6) ---> 13
Solución:
78
8.4.7 Ejercicio: Comparar mediante TRACE y TIME las dos defini-
ciones anteriores de la función de FIBONACCI.
8.4.8 Ejercicio: Escribir la función de 91 de McCarthy
½
N - 10 si N > 100
F91(N) =
F91(F91(N + 11)) si 0 ≤ N ≤ 100
Solución:
; DEFINICION NO RECURSIVA
(ACK 3 4)
(TIME ’(ACK 3 4))
Solución:
79
(DEFUN ACK (M N)
(COND ((= M 0) (1+ N))
((= N 0) (ACK (1- M) 1))
(T (ACK (1- M) (ACK M (1- N))))))
80
Capı́tulo 9
Lectura y escritura
* (PRINT (+ 2 3))
5
5
Solución:
81
9.1.4 Definición: Las funciones PRIN1 y PRINC:
9.1.5 Ejemplo:
* (PRIN1 "A")
"A"
"A"
* (PRINC "A")
A
"A"
* (TAB-CUAD 3)
EL CUADRADO DE 1 ES 1
EL CUADRADO DE 2 ES 4
EL CUADRADO DE 3 ES 9
NIL
Solución:
82
(DEFUN TAB-CUAD (N)
(PROG (AUX)
(SETQ AUX 1)
ETIQUETA
(COND ((> AUX N) (RETURN))
(T (TERPRI)
(PRINC "EL CUADRADO DE ")
(PRINC AUX)
(PRINC " ES ")
(PRINC (* AUX AUX))
(SETQ AUX (1+ AUX))
(GO ETIQUETA) ))))
(QUOTE A)
* (SETQ A (READ))
2
2
* A
2
* (+ (READ) (READ))
3
4
83
Por ejemplo,
* (CALCULA-CUADRADOS)
EL CUADRADO DE 3
ES 9
EL CUADRADO DE 5
ES 25
EL CUADRADO DE A
FIN
NIL
Solución:
(DEFUN CALCULA-CUADRADOS ()
(PROG (AUX)
ETIQUETA
(TERPRI)
(PRINC "EL CUADRADO DE ")
(SETQ AUX (READ))
(COND ((NOT (NUMBERP AUX)) (PRINC "FIN") (TERPRI))
(T (PRINC "ES ")
(PRINC (* AUX AUX))
(TERPRI)
(GO ETIQUETA) ))))
84
9.1.11 Ejemplo:
* (CUADRADOS 2 5)
EL CUADRADO DE 2 ES 4
EL CUADRADO DE 3 ES 9
EL CUADRADO DE 4 ES 16
EL CUADRADO DE 5 ES 25
FIN
Solución:
(DEFUN CUADRADOS (M N)
(DO ((CONT M (1+ CONT)))
((> CONT N) ’FIN)
(FORMAT T
"~%EL CUADRADO DE ~D ES ~D"
CONT (* CONT CONT)) ))
85
9.2 Funciones de lectura y escritura sobre
ficheros
9.2.1 Apertura de un fichero:
9.2.3 Ejemplo:
86
9.2.4 Definición: La función WITH-OPEN-FILE:
9.2.5 Ejemplo:
Definir la función que LEE que lea el contenido del fichero. Por ejemplo:
87
* (LEE)
((AGUADO CASAS) (JUAN JOSE) 5)
((AGUILA PUENTE) (RAFAEL) 2)
((ALBA ADAME) (CARLOS) 9)
((ALCALDE PEREZ) (MARIA LUISA) 3)
NIL
Solución:
(DEFUN LEE ()
(WITH-OPEN-FILE (NOTAS "NOTAS.DAT" :DIRECTION :INPUT)
(DO ((ALUMNO (READ NOTAS NIL)
(READ NOTAS NIL) ))
((NOT ALUMNO))
(TERPRI)
(PRINC ALUMNO) )))
(DEFUN APROBADOS ()
(WITH-OPEN-FILE (NOTAS "NOTAS.DAT" :DIRECTION :INPUT)
(WITH-OPEN-FILE (APROBADOS "APROBADOS.DAT" :DIRECTION :OUTPUT)
(DO ((ALUMNO (READ NOTAS NIL)
(READ NOTAS NIL) ))
((NOT ALUMNO))
(WHEN (APROBADO-P ALUMNO)
(PRINC ALUMNO APROBADOS)
(TERPRI APROBADOS) )))))
88
Escribir las siguientes funciones:
Por ejemplo,
* (BUSCAR ’PEPE)
(PEPE SIERPES-12 "4531420")
* (CAMBIAR-DIR ’PEPE ’TARFIA-SN)
(PEPE TARFIA-SN "4531420")
* (BUSCAR ’PEPE)
(PEPE TARFIA-SN "4531420")
* (CAMBIAR-TEL ’PEPE "4615600")
(PEPE TARFIA-SN "4615600")
* (BUSCAR ’PEPE)
(PEPE TARFIA-SN "4615600")
* (QUITAR ’PEPE)
((JUAN CUNA-5 "4243568"))
* (PONER ’PEPE ’TARFIA-SN "4615600")
((PEPE TARFIA-SN "4615600") (JUAN CUNA-5 "4243568"))
* (CERRAR)
NIL
* AGENDA
89
ERROR:
Unbound variable: AGENDA
1> <Control C>
* (ABRIR)
* AGENDA
((PEPE SIERPES-12 "4531420")(JUAN CUNA-5 "4243568")))
* (AGENDA)
1: LEER BASE DE DATOS 5: QUITAR NOMBRE
ESCRIBE OPCION: 1
ESCRIBE OPCION: 6
ESCRIBE OPCION: 6
ESCRIBE OPCION: 2
90
NOMBRE: JUAN
DIRECCION: TARFIA-SN
TELEFONO: 4616500
ESCRIBE OPCION: 7
ESCRIBE OPCION: 8
"FIN"
Solución:
91
(IF (BOUNDP ’AGENDA)
(SETQ AGENDA (CONS (LIST NOMBRE DIRECCION TELEFONO) AGENDA))
(SETQ AGENDA (LIST (LIST NOMBRE DIRECCION TELEFONO))) ))
(DEFUN CERRAR ()
(LET ((AUX (OPEN "AGENDA.DAT" :DIRECTION :OUTPUT)))
(PRIN1 AGENDA AUX)
(MAKUNBOUND ’AGENDA)
(CLOSE AUX) ))
(DEFUN ABRIR ()
(LET ((AUX (OPEN "AGENDA.DAT" :DIRECTION :INPUT)))
(SETQ AGENDA (READ AUX))
(CLOSE AUX) ))
(DEFUN MENU ()
(FORMAT T
"~% 1: LEER BASE DE DATOS 5: QUITAR NOMBRE
~% 2: BUSCAR UN NOMBRE 6: PONER NOMBRE
~% 3: CAMBIAR DIRECCION 7: GRABAR BASE DE DATOS
~% 4: CAMBIAR TELEFONO 8: SALIR
~%") )
(DEFUN AGENDA ()
(SEND *TERMINAL-IO* :CLEAR-SCREEN) ;LIMPIA LA PANTALLA
(MENU)
(SETQ AGENDA NIL)
(LOOP
(FORMAT T "~%ESCRIBE OPCION: ")
(LET ((AUX (READ)))
(SEND *TERMINAL-IO* :CLEAR-SCREEN)
(MENU)
(COND ((EQUAL AUX 1) (ABRIR) )
((EQUAL AUX 2)
(FORMAT T "~%ESCRIBE EL NOMBRE: ")
(SETQ PP (BUSCAR (READ)))
(IF PP (FORMAT T
"~%NOMBRE: ~A ~%DIRECCION: ~A ~%TELEFONO: ~A"
(CAR PP) (CADR PP) (CADDR PP))
(FORMAT T "~%NO ESTA EN LA AGENDA") )
(MAKUNBOUND ’PP)
92
(TERPRI) )
((EQUAL AUX 3)
(FORMAT T "~%ESCRIBE NOMBRE: ")
(SETQ NOMBRE (READ))
(FORMAT T "~%ESCRIBE NUEVA DIRECCION: ")
(CAMBIAR-DIR NOMBRE (READ))
(MAKUNBOUND NOMBRE) )
((EQUAL AUX 4)
(FORMAT T "~%ESCRIBE NOMBRE: ")
(SETQ NOMBRE (READ))
(FORMAT T "~%ESCRIBE NUEVO NUMERO DE TELEFONO: ")
(CAMBIAR-TEL NOMBRE (READ-LINE))
(MAKUNBOUND NOMBRE) )
((EQUAL AUX 5)
(FORMAT T "~%ESCRIBE NOMBRE: ")
(QUITAR (READ)) )
((EQUAL AUX 6)
(FORMAT T "~%ESCRIBE NOMBRE: ")
(SETQ NOMBRE (READ))
(FORMAT T "~%ESCRIBE DIRECCION: ")
(SETQ DIRECCION (READ))
(FORMAT T "~%ESCRIBE TELEFONO: ")
(SETQ TELEFONO (READ-LINE))
(PONER NOMBRE DIRECCION TELEFONO)
(MAKUNBOUND ’NOMBRE)
(MAKUNBOUND ’DIRECCION)
(MAKUNBOUND ’TELEFONO) )
((EQUAL AUX 7) (CERRAR) )
((EQUAL AUX 8) (SEND *TERMINAL-IO* :CLEAR-SCREEN)
(RETURN "FIN") )))))
93
Bibliografı́a
94
17. ROY, J.P.; KIREMITDJIAN, G. Lire LISP CEDIC, Paris, 1985.
18. SIKLOSSY, L. Let’s Talk LISP Prentice-Hall, London, 1976.
19. STEELE, G.L. Common LISP: The Language Digital Press, 1984.
20. TOURETZKY, D.S. LISP: Introducción al cálculo simbólico Dı́az
de Santos,
Madrid, 1986.
21. WERTZ, H. LISP, Introducción a la programación Masson, Barcelona,
1986.
22. WERTZ, H. LISP, une introduction à la programmation Masson,
Paris, 1985.
23. WILENSKY, R. LISPcraft Norton, New York, 1984.
24. WINSTON, P.H.; HORN, B.K.P. LISP (3 edition) Addison Wes-
ley, 1988.
95