LECCION 4. FUNCIONES (II).

Anuncio
LECCION 4. FUNCIONES (II).
En esta lección se aplican las técnicas y los recursos expuestos en las lecciones
anteriores. En primer lugar, se profundiza en las técnicas de programación.
Por otra parte, se muestra cómo es posible simular el paso de mensajes y las funciones
genéricas mediante cierres léxicos.
“LAMBDA, el GOTO definitivo”
(Guy L. Steele, jr.)
Inteligencia Artificial e I.C.. 2002/03
4.1
Dpto. Leng. Ciencias Comp.
Inteligencia Artificial e I.C.. 2002/03
4.2
Dpto. Leng. Ciencias Comp.
R.4.1. Filtrado de listas (I)
Definir las siguientes funciones:
a) Mi-remove-if y mi-remove-if-not, que tienen dos argumentos: un predicado p (de un argumento) y
una lista L. Mi-remove-if devuelve una lista formada por los elementos de L que no satisfacen p.
Mi-remove-if-not devuelve una lista formada por los elementos de L que satisfacen p.
b) Mi-substitute-if, que tiene tres argumentos: una expresión e, un predicado p (de un argumento) y
una lista L. Mi-substitute-if devuelve una lista formada por los mismos elementos que L, salvo los
que satisfacen p, que son sustituidos por e.
c) Mi-some y mi-every, que tienen dos argumentos: un predicado p (de un argumento) y una lista L.
Mi-some devuelve T si algún elemento de ,L satisface p, NIL en otro caso. Mi-every devuelve T si
todos los elementos de L satisfacen p, NIL en otro caso.
d) Mi-find-if, que tiene dos argumentos: un predicado p (de un argumento) y una lista L. Mi-find-if
devuelve el primer elemento de L que satisface p, o NIL si ninguno lo satisface.
**************************
SOLUCION:
a) Podemos dar una definición recursiva directa: si L es NIL, el valor es NIL; en otro caso, si car(L)
satisface p, el valor es el resultado de aplicar la función sobre cdr(L); en otro caso, el valor es el
resultante de CONSar car(L) con el resultado de aplicar la función sobre cdr(L). En Lisp
(DEFUN MI-REMOVE-IF (P L)
(COND ((NULL L) NIL)
((FUNCALL P (CAR L)) (MI-REMOVE-IF P (CDR L)))
(T (CONS (CAR L) (MI-REMOVE-IF P (CDR L))))))
De MI-REMOVE-IF-NOT también podemos dar una definición directa; pero, ¿para qué escribir
tanto? Definamos la función inversa-booleana:
(DEFUN INVERSA-BOOLEANA (P)
#'(LAMBDA (X) (NOT (FUNCALL P X))))
y será simplemente
(DEFUN MI-REMOVE-IF-NOT (P L)
(MI-REMOVE-IF (INVERSA-BOOLEANA P) L))
b) Como antes, podemos dar una definición recursiva directa; pero anora la daremos empleando
MAPCAR. Para cada elemento en de L devolvemos e o bien el mismo en, según satisfaga o no el
predicado p. En Lisp
(DEFUN MI-SUBSTITUTE-IF (E P L)
(MAPCAR #'(LAMBDA (X) (IF (FUNCALL P X) E X)) L))
c) Análogamente
(DEFUN MI-SOME (P L)
(COND ((NULL L) NIL)
((FUNCALL P (CAR L)) T)
(T (MI-SOME P (CDR L)))))
y
(DEFUN MI-EVERY (P L)
(COND ((NULL L) T)
((FUNCALL P (CAR L)) (MI-EVERY P (CDR L)))
(T NIL)))
o bien
(DEFUN MI-EVERY (P L)
(NOT (MI-SOME (INVERSA-BOOLEANA P) L)))
d) Por último
(DEFUN MI-FIND-IF (P L)
(COND ((NULL L) NIL)
((FUNCALL P (CAR L)) (CAR L))
(T (MI-FIND-IF P (CDR L)))))
NOTA. Todas estas funciones están predefinidas en Common Lisp. Su definición es más general,
pues no sólo se aplican a listas, sino a sucesiones (listas, vectores y cadenas).
NOTA. Todas estas funciones tienen un "aire de familia"; es posible abstraer un grado más y
definirlas como instancias de una función de reducción o plegado (vd. R.4.3)
Inteligencia Artificial e I.C.. 2002/03
4.3
Dpto. Leng. Ciencias Comp.
R.4.2. Filtrado de listas (II).
a) Definir en Lisp la función substitute-if-2, que tiene tres argumentos: un predicado binario p, una
función binaria f y una lista L. Substitute-if-2 devuelve una lista formada a partir de L suprimiendo el
primer par de elementos consecutivos e, e’ de L tales que satisfacen p(e, e’), y sustituyéndolos por
f(e, e’). Si no existe tal par, se devuelve la misma L. Por ejemplo
(SUBSTITUTE-IF-2 #'< #'+ '(6 4 2 3 10 8)) => (6 4 5 10 8)
(SUBSTITUTE-IF-2 #'= #'+ '(6 4 2 3 10 8)) => (6 4 2 3 10 8)
b) Definir en Lisp la función substitute-if-n, que tiene tres argumentos: un predicado p (de dos
argumentos), una función binaria f y una lista L. Substitute-if-n devuelve una lista calculada
aplicando sucesivamente substitute-if-2, hasta que se alcance un valor fijo.
c) La sucesión de Hilgemeier {hi} es una sucesión de listas de enteros dada por
(1)
es decir, un uno
h0 =
(1 1)
es decir, dos unos
h1 =
h2 =
(2 1)
es decir, un dos un uno
h3 =
(1 2 1 1)
es decir, un uno un dos dos unos
h4 =
(1 1 1 2 2 1)
...
hi+1 = la descripción de hi escrita como lista de números.
Definir la función HILGE(n), que devuelve el n-ésimo término de la sucesión de Hilgemeier.
**************************
SOLUCION:
a)Si L esta vacía o consta de un solo valor es L; en otro caso, si los dos primeros elementos
satisfacen p, se devuelve la lista formada CONSando f(car(L), cadr(L)) y cdr(L); en otro caso se
recurre sobre cdr(L). En Lisp
(DEFUN SUBSTITUTE-IF-2 (P F L)
(COND ((NULL L) NIL)
((NULL (CDR L)) L)
((FUNCALL P (CAR L) (CADR L))
(CONS (FUNCALL F (CAR L) (CADR L)) (CDDR L)))
(T (CONS (CAR L) (SUBSTITUTE-IF-2 P F (CDR L))))))
b) Lo que se está definiendo es la función de punto fijo correspondiente a SUBSTITUTE-IF-2.
Definamos la función "punto fijo", que tiene como argumentos una función f y una expresión
prueba, y devuelve el primer valor de la sucesión {ei }dada por e0 =prueba, ei+1 =f(ei) tal que ei+1=ei:
(DEFUN PUNTO-FIJO (F PRUEBA)
(COND ((EQUAL PRUEBA (FUNCALL F PRUEBA)) PRUEBA)
(T (PUNTO-FIJO F (FUNCALL F PRUEBA)))))
Para no llamar dos veces a F, podemos introducir una función auxiliar:
(DEFUN PUNTO-FIJO (F PRIMERA-PRUEBA)
(PUNTO-FIJO-AUX F PRIMERA-PRUEBA (FUNCALL F PRIMERA-PRUEBA)))
(DEFUN PUNTO-FIJO-AUX (F S FS)
(COND ((EQUAL S FS) S)
(T (PUNTO-FIJO-AUX F FS (FUNCALL F FS)))))
Y aún podemos mejorar esta definición, considerando que el predicado de igualdad se puede
pasar como argumento a PUNTO-FIJO:
(DEFUN PUNTO-FIJO (F PRIMERA-PRUEBA P)
(PUNTO-FIJO-AUX F PRIMERA-PRUEBA (FUNCALL F PRIMERA-PRUEBA) P))
(DEFUN PUNTO-FIJO-AUX (F S FS P)
(COND ((FUNCALL P S FS) S)
(T (PUNTO-FIJO-AUX F FS (FUNCALL F FS) P))))
Ahora SUBSTITUTE-IF-N será simplemente
(DEFUN SUBSTITUTE-IF-N (PRED F LISTA)
(PUNTO-FIJO #'(LAMBDA (L) (SUSBSTITUTE-IF-2 PRED F L)) LISTA))
Inteligencia Artificial e I.C.. 2002/03
4.4
Dpto. Leng. Ciencias Comp.
El punto fijo se alcanza en un número finito de pasos: en efecto, (REPLACE-IF-2 P L) devuelve
o bien L, en cuyo caso ya se ha llegado al punto fijo, o bien una lista de longitud inferior en una
unidad, lo cual sólo puede ocurrir un número finito de veces.
c) La definición recursiva es fácil, supuesta definida sig-hilge que calcula el siguiente elemento de
la sucesión:
(DEFUN HILGE (N)
(COND ((ZEROP N) (LIST 1))
( T (SIG-HILGE (HILGE (1- N))))))
El valor de sig-hilge(L) puede calcularse de muchas formas. La que proponemos aquí es elegante
(aunque no necesariamente eficiente):
1) contemos una vez cada elemento de L, creando así una lista de listas L’. Por ejemplo, si L es
(1 1 1 2 2 1)
L’ será
((1 1) (1 1) (1 1) (1 2) (1 2) (1 1))
Ello equivale a calcular la lista L’, formada a partir de L LISTando cada uno de sus elementos y el
número 1. Es decir, L’ es el resultado de aplicar #'(LAMBDA (X) (LIST 1 X)) a cada elemento
de L, o sea, L’ es el resultado de (MAPCAR #'(LAMBDA (X) (LIST 1 X)) L). Por ejemplo, si
L es
(1 1 1 2 2 1)
L’ será
((1 1) (1 1) (1 1) (1 2) (1 2) (1 1))
2) si dos cuentas consecutivas se refieren al mismo valor, debemos acumularlas en una sola
cuenta. Por ejemplo, si L’ es
((1 1) (1 1) (1 1) (1 2) (1 2) (1 1))
debemos quedarnos con
((2 1) (1 1) (1 2) (1 2) (1 1)),
((3 1) (1 2) (1 2) (1 1))
y finalmente con
((3 1) (2 2) (1 1))
Ello equivale a aplicar a L’ el proceso REPLACE-IF-N con predicado
#'(LAMBDA (L1 L2) (= (CADR L1) (CADR L2)))
y función de reemplazamiento
#'(LAMBDA (L1 L2) (LIST (+ (CAR L1) (CAR L2)) (CADR L1)))
3) Formemos una sola lista con los pares que finalmente hayan quedado. Es decir, APPLYamos
#'APPEND al resultado anterior.
En Lisp
(DEFUN SIG-HILGE (L)
(APPLY
#'APPEND
(REPLACE-IF-N
#'(LAMBDA (L1 L2)
(= (CADR L1) (CADR L2)))
#'(LAMBDA (L1 L2)
(LIST (+ (CAR L1) (CAR L2)) (CADR L1)))
(MAPCAR
#'(LAMBDA (X)
(LIST 1 X))
L))))
Inteligencia Artificial e I.C.. 2002/03
4.5
Dpto. Leng. Ciencias Comp.
R.4.6. Programación por paso de mensajes.
Deseamos diseñar un programa para representar y manejar cuadrados y triángulos equiláteros,
definidos ambos por las coordenadas de su centro y la longitud de su lado. El programa debe ser
capaz de calcular las áreas y los perímetros de estas figuras.
a)Definir una implementación Lisp basada en el paso de mensajes, en la que los objetos se
representen como cierres léxicos.
b)En esta implementación, trazar la evaluación de
(PERIMETRO (HACER CUADRADO 210 120 1))
c)Modificar la implementación para tratar también los círculos, definidos por su centro y radio.
d)Modificar la implementación para calcular también los diámetros de los objetos. Se entiende por
diámetro de un polígono la longitud del mayor segmento que puede trazarse en el interior del
polígono: para el cuadrado es la diagonal y para el triángulo equilátero el lado.
**************************
SOLUCION:
a)En R.2.8 representábamos los objetos mediante listas, y las operaciones sobre los objetos
mediante un conjunto de funciones independientes de estas listas. En la representación basada en
cierres léxicos se adopta un punto de vista radicalmente opuesto: cada objeto se encarga de definir
sus propias funciones. Los constructores son por tanto más complejos:
(DEFUN HACER-TRIANGULO (X Y L)
#'(LAMBDA (MSJ)
(CASE MSJ (LADO L)
(CENTROX X)
(CENTROY Y)
(ALTURA (* 0.5 (SQRT 3) L))
(AREA (* 0.5 L (* 0.5 (SQRT 3) L)))
(PERIMETRO (* 3 L)))))
(DEFUN HACER-CUADRADO (X Y L)
#'(LAMBDA (MSJ)
(CASE MSJ (LADO L)
(CENTROX X)
(CENTROY Y)
(ALTURA L)
(AREA (* L L))
(PERIMETRO (* 4 L)))))
Por el contrario, las funciones son muy sencillas. Definimos un aplicador genérico
(DEFUN OPERAR (MSJ OBJ) (FUNCALL OBJ MSJ))
Y, si lo deseamos, podemos dar nombres a las operaciones especificadas:
(DEFUN LADO (OBJ) (OPERAR ´LADO OBJ))
(DEFUN CENTROX (OBJ) (OPERAR 'CENTROX OBJ))
(DEFUN CENTROY (OBJ) (OPERAR 'CENTROY OBJ))
(DEFUN ALTURA (OBJ) (OPERAR 'ALTURA OBJ))
(DEFUN AREA (OBJ) (OPERAR 'AREA OBJ))
(DEFUN PERIMETRO (OBJ) (OPERAR 'PERIMETRO OBJ))
b) Evaluemos el argumento
(HACER-CUADRADO 210 120 1)
=>
X <- 210
Y <- 120
L <- 1
#'(LAMBDA (MSJ)
(CASE MSJ (LADO) L)
(CENTROX X)
(CENTROY Y)
(ALTURA L)
(AREA (* L L))
(PERIMETRO (* 4 L))))
Inteligencia Artificial e I.C.. 2002/03
4.6
Dpto. Leng. Ciencias Comp.
Llamemos C1 a este cierre léxico. Ahora se puede evaluar la expresión propuesta:
(PERIMETRO (HACER-CUADRADO 210 120 1)) ==
OBJ <- C1
(OPERAR 'PERIMETRO OBJ) ==
OBJ <- C1
MSJ <- PERIMETRO
(FUNCALL OBJ MSJ) ==
(* 4 1) =>
4
c)Es necesario añadir un constructor de círculos:
(DEFUN HACER-CIRCULO (X Y R)
#'(LAMBDA (MSJ)
(CASE MSJ (RADIO R)
(CENTROX X)
(CENTROY Y)
(AREA (* PI R R))
(PERIMETRO (* 2 PI R)))))
y añadir la nueva función RADIO:
(DEFUN RADIO (OBJ) (OPERAR ´RADIO OBJ))
El resto permanece igual.
d)Es necesario modificar todos los constructores:
(DEFUN HACER-TRIANGULO (X Y L)
#'(LAMBDA (MSJ)
(CASE MSJ (LADO L)
(CENTROX X)
(CENTROY Y)
(ALTURA (* 0.5 (SQRT 3) X))
(AREA (* 0.5 L (* 0.5 (SQRT 3) X)))
(PERIMETRO (* 3 L))
(DIAMETRO L))))
(DEFUN HACER-CUADRADO (X Y L)
#'(LAMBDA (MSJ)
(CASE MSJ (LADO L)
(CENTROX X)
(CENTROY Y)
(ALTURA L)
(AREA (* L L))
(PERIMETRO (* 4 L))
(DIAMETRO (* (SQRT 2) L)))))
(DEFUN HACER-CIRCULO (X Y R)
#'(LAMBDA (MSJ)
(CASE MSJ (RADIO R)
(CENTROX X)
(CENTROY Y)
(AREA (* PI R R))
(PERIMETRO) (* 2 PI R))
(DIAMETRO (* 2 R)))))
y añadir la nueva función DIAMETRO:
(DEFUN DIAMETRO (OBJ) (OPERAR ´DIAMETRO OBJ))
Inteligencia Artificial e I.C.. 2002/03
4.7
Dpto. Leng. Ciencias Comp.
R.4.7. Programación dirigida por los datos.
Diseñar una implementación alternativa para los apartados a), b), c) de R.4.6, en la que los objetos
se representen por listas y exista un operador genérico OPERAR; la manera de efectuar las
operaciones será mediante llamadas (OPERAR operación objeto)
**************************
SOLUCION:
a)Podemos emplear los mismos constructores y predicados de tipo que en R.2.8:
(DEFUN HACER-TRIANGULO (X Y L) (LIST 'TRIANGULO X Y L))
(DEFUN HACER-CUADRADO (X Y L) (LIST 'CUADRADO X Y L))
(DEFUN TIPO (OBJ) (CAR OBJ))
(DEFUN TRIANGULO-P (OBJ) (EQ (TIPO OBJ) 'TRIANGULO))
(DEFUN CUADRADO-P (OBJ) (EQ (TIPO OBJ) 'CUADRADO))
Sin embargo, las funciones deben implementarse de otra forma para permitir la definición de
OPERAR. Definiremos una pequeña función anónima para cada operación sobre cada tipo de
objeto; por ejemplo, el lado del cuadrado será
(LAMBDA (OBJ) (CADDDR OBJ))
El perímetro del cuadrado será
(LAMBDA (OBJ) (* 4 (CADDDR OBJ)))
y análogamente los demás casos. Todas estas funciones anónimas se ponen en correspondencia
con los tipos mediante una tabla, que para cada tipo y nombre de operación devuelve la función que
corresponde:
(DEFUN TABLA (OPERACION TIPO)
(CASE TIPO
(TRIANGULO
(CASE OPERACION (LADO #'(LAMBDA (OBJ) (CADDDR OBJ)))
(CENTROX #'(LAMBDA (OBJ) (CADR OBJ)))
(CENTROY #'(LAMBDA (OBJ) (CADDR OBJ)))
(ALTURA #'(LAMBDA (OBJ)
(* 0.5 (SQRT 3) (OPERAR 'LADO OBJ))))
(AREA #'(LAMBDA (OBJ) (* 0.5 (OPERAR 'LADO OBJ)
(OPERAR 'ALTURA OBJ))))
(PERIMETRO #'(LAMBDA (OBJ)
(* 3 (OPERAR 'LADO OBJ))))))
(CUADRADO
(CASE OPERACION (LADO #'(LAMBDA (OBJ) (CADDDR OBJ)))
(CENTROX #'(LAMBDA (OBJ) (CADR OBJ)))
(CENTROY #'(LAMBDA (OBJ) (CADDR OBJ)))
(ALTURA #'(LAMBDA (OBJ) (OPERAR 'LADO OBJ)))
(AREA #'(LAMBDA (OBJ) (* (OPERAR 'LADO OBJ)
(OPERAR 'ALTURA OBJ))))
(PERIMETRO #'(LAMBDA (OBJ)
(* 4 (OPERAR 'LADO OBJ))))))))
La función OPERAR genérica será simplemente
(DEFUN OPERAR (OPERACION OBJ)
(FUNCALL (TABLA OPERACION (TIPO OBJ)) OBJ))
c )Añadimos el constructor de círculos:
(DEFUN HACER-CIRCULO (X Y R) (LIST ´CIRCULO X Y R))
(DEFUN CIRCULO-P (OBJ) (EQ (TIPO OBJ) ´CIRCULO))
Consideramos las funciones elementales necesarias: por ejemplo, para el radio
(LAMBDA (OBJ) (CADDDR OBJ))
Para el área
(LAMBDA (OBJ) (* PI (OPERAR 'RADIO OBJ) (OPERAR 'RADIO OBJ)))
Inteligencia Artificial e I.C.. 2002/03
4.8
Dpto. Leng. Ciencias Comp.
Y para el perímetro
(LAMBDA (OBJ) (* 2 PI (OPERAR 'RADIO OBJ)))
Y las insertamos en la tabla:
(DEFUN TABLA (OPERACION TIPO)
(CASE TIPO
(CIRCULO
(CASE OPERACION (RADIO #'(LAMBDA (OBJ) (CADDDR OBJ)))
(CENTROX #'(LAMBDA (OBJ) (CADR OBJ)))
(CENTROY #'(LAMBDA (OBJ) (CADDR OBJ)))
(ALTURA #'(LAMBDA (OBJ)
(* 0.5 (SQRT 3) (OPERAR 'LADO OBJ))))
(AREA #'(LAMBDA (OBJ) (* PI (OPERAR 'RADIO OBJ)
(OPERAR 'RADIO OBJ))))
(PERIMETRO #'(LAMBDA (OBJ)
(* 2 PI (OPERAR 'RADIO OBJ))))))
(TRIANGULO
(CASE OPERACION (LADO #'(LAMBDA (OBJ) (CADDDR OBJ)))
(CENTROX #'(LAMBDA (OBJ) (CADR OBJ)))
(CENTROY #'(LAMBDA (OBJ) (CADDR OBJ)))
(ALTURA #'(LAMBDA (OBJ)
(* 0.5 (SQRT 3) (OPERAR 'LADO OBJ))))
(AREA #'(LAMBDA (OBJ) (* 0.5 (OPERAR 'LADO OBJ)
(OPERAR 'ALTURA OBJ))))
(PERIMETRO #'(LAMBDA (OBJ)
(* 3 (OPERAR 'LADO OBJ))))))
(CUADRADO
(CASE OPERACION (LADO #'(LAMBDA (OBJ) (CADDDR OBJ)))
(CENTROX #'(LAMBDA (OBJ) (CADR OBJ)))
(CENTROY #'(LAMBDA (OBJ) (CADDR OBJ)))
(ALTURA #'(LAMBDA (OBJ) (OPERAR 'LADO OBJ)))
(AREA #'(LAMBDA (OBJ) (* (OPERAR 'LADO OBJ)
(OPERAR 'ALTURA OBJ))))
(PERIMETRO #'(LAMBDA (OBJ)
(* 4 (OPERAR 'LADO OBJ))))))))
d) Añadimos las operaciones elementales necesarias:
Para el diámetro del círculo:
(LAMBDA (OBJ) (* 2 (RADIO OBJ)))
Para el diámetro del cuadrado:
(LAMBDA (OBJ) (* (SQRT 2) (LADO OBJ)))
y las insertamos en la tabla:
Modificamos la tabla, insertando estas nuevas funciones:
(DEFUN TABLA (OPERACION TIPO)
(CASE TIPO
(CIRCULO
(CASE OPERACION (DIAMETRO #'(LAMBDA (OBJ) (* 2 (RADIO OBJ)))
...
...))
(TRIANGULO
(CASE OPERACION (DIAMETRO #'(LAMBDA (OBJ) (CADDDR OBJ)))
...
...))
(CUADRADO
(CASE OPERACION (DIAMETRO #'(LAMBDA (OBJ) (* (SQRT 2)
(LADO OBJ))))
...
...))))
Inteligencia Artificial e I.C.. 2002/03
4.9
Dpto. Leng. Ciencias Comp.
EJERCICIOS PROPUESTOS.
P.4.1. Definir las siguientes funciones:
a) Remove-if-tree, que tiene como argumentos un predicado unitario p y una lista con anidamientos
L, y devuelve la lista formada suprimiendo en L aquellos átomos que satisfacen p. Por ejemplo, si p
es ZEROP y L es ((3 0) (4 (0 0))), se devuelve ((3) (4 ())).
b) Replace-if-tree, que tiene como argumentos un predicado unitario p, una función f y una lista con
anidamientos L, y devuelve la lista formada sustituyendo en L cada átomo x que satisface p por f(x).
Por ejemplo, si p es ZEROP, f es la función sucesor y L es ((3 0) (4 (0 0))), se devuelve ((3 1) (4 (1
1)))
P.4.2. a) Definir una función Lisp de argumento k que compruebe para todos los valores naturales
menores que k la validez del siguiente enunciado: “No existen números naturales x, y, z tales que
3
3
3
x +y =z”
b)Definir la función Lisp (CRIBA N), que devuelve la sucesión de todos los números primos hasta
N empleando la criba de Eratóstenes.
P.4.3. La sucesión de Ulam {Ui} se define como sigue: {Ui} es una sucesión creciente de números
tal naturales tal que
U1 = 1
U2 = 2
y para todo n∈N, n aparece en la sucesión si y sólo si n se puede expresar de manera única como
suma de dos elementos anteriores de la sucesión. Definir la función Lisp (ULAM N) que devuelve
los elementos de la sucesión de Ulam comprendidos entre 1 y N.
P.4.4. Supongamos dos funciones f y g de la misma aridad n que devuelven valores naturales. Se
dice que f y g son extensionalmente iguales cuando para toda n-tupla (a1, ..., an), f(a1, ..., an) = g(a1,
..., an). ¿Es posible implementar una función EQUAL-F que tenga como argumentos dos funciones
y devuelva “verdadero” cuando ambas funciones sean extensionalmente iguales, “falso” en otro
caso?
P.4.6. Deseamos diseñar un programa para representar y manejar cubos y tetraedros, definidos
ambos por las coordenadas de su centro y la longitud de su arista. El programa debe ser capaz de
calcular los volúmenes y las superficies de estas figuras.
a)Definir una implementación Lisp basada en el paso de mensajes, en la que los objetos se
representen como cierres léxicos.
b) Modificar la implementación dada en a) para representar también las esferas. Cada esfera se
identifica por su radio y las coordenadas de su centro.
P.4.7. Repetir el ejercicio P.4.6, empleando esta vez el paradigma de programación basada en el
paso de mensajes.
Inteligencia Artificial e I.C.. 2002/03
4.10
Dpto. Leng. Ciencias Comp.
NOTAS ERUDITAS Y CURIOSAS.
Las técnicas de filtrado son características de la programación funcional. Sin embargo, hay que
señalar que su uso efectivo exige el empleo de la llamada evaluación “perezosa” y de las
corrientes o “streams”.
La asignación de un significado funcional f a un símbolo s con
DEFUN permite definir f de manera recursiva, empleando el
nombre s en el cuerpo de su misma definición. Pero, como señala
McCarthy (McCarthy, 1981), parecía deseable que la notación
empleada para denotar argumentos funcionales explícitos -sin un
DEFUN previo- fuera capaz de representar la recursividad. Una
primera solución para ello -propuesta por Nataniel Rochester- fue
hacer que las funciones anónimas dejaran de serlo, mediante la
forma LABEL. De esta manera, se podían pasar argumentos
funcionales recursivos como por ejemplo (la sintaxis actual es
algo diferente, vd. lección 5)
Figura IV.1. Harold Abelson.
(LABEL PEPE (LAMBDA (L) (COND ((NULL L NIL) (T (PEPE (CDR L)))))
Sin embargo, David Park (1935-1990) -entonces un alumno
del MIT, enseguida uno de los “padres” de la Informática
Teórica- señaló que desde el punto de vista lógico la
construcción anterior era innecesaria, ya que algo parecido
al combinador Y del lambda-cálculo podía representar el
mismo papel.
En el lambda cálculo, se demuestra la existencia de una
expresión Y tal que para toda expresión E,
(Y)E => (E)(Y)E => (E)(E)(Y)E => ... => (E)...(E)(Y)E.
Esta expresión Y es
λy.(λx.(y)(x)x)λx.(y)(x)x
Ahora bien, toda definición recursiva de una función de
orden superior E implica una ecuación de punto fijo de la
forma
X = (E) X
Nótese que, sustituyendo X por (Y)E queda
(Y)E = (E) (Y)E
que, como hemos dicho, es una propiedad del combinador Figura IV.2. David Park en 1960.
Y. Por tanto, el combinador Y permite prescindir de la
recursión.
Las técnicas de “programación por paso de mensajes” y “programación dirigida por los datos”
han sido expuestas con claridad difícilmente superable por Abelson y Sussman en SICP
(Abelson y Sussman 85). El modelo de paso de mensajes es el que subyace en los lenguajes
convencionales de programación orientada a objetos; el modelo de programación dirigida por
los datos es el que subyace en CLOS (Common Lisp Object System)
Inteligencia Artificial e I.C.. 2002/03
4.11
Dpto. Leng. Ciencias Comp.
Descargar