Document

Anuncio
PLP - Recuperatorio Primer Parcial - 2o cuatrimestre de 2005
Este examen se aprueba obteniendo al menos 70 puntos. Poner nombre, apellido y número
de orden en cada hoja, y numerarlas. Se puede utilizar todo lo definido en las prácticas y todo
lo que se dio en clase, colocando referencias claras.
Ejercicio 1 - Inferencia de tipos
a) (15 puntos) Mostrar que el siguiente término no es tipable. Justificar mostrando el árbol
sintáctico correspondiente e indicar cuáles fueron las reglas aplicadas a cada nodo del árbol.
(λx.(head x) + 1) 2
Agregar la unificación realizada en cada uno de los nodos donde se usó la regla de aplicación.
Asumir que son conocidos los tipos de las siguientes funciones:
head :: [a]->a
+ :: Int->Int->Int
b) (20 puntos) Se pide presentar una extensión del algoritmo de inferencia visto en clase para
que, además de devolver el tipo de un pseudo término φ, nos pueda indicar si hay garantı́as
de que φ sea una función total. Como es sabido, no es posible determinar si una función es
total o parcial para el caso general, pero bajo ciertas condiciones esto sı́ es factible.
El algoritmo extendido, que llamaremos P T ext , va a tomar como entrada un término φ (de
la misma forma que PT, el algoritmo original) sobre el que se desea aplicar el proceso de
inferencia. Además de esto, va a recibir un conjunto C de sı́mbolos de función que representa
a las funciones que se sabe que son totales. Se asume que el tipo de las funciones de C es
siempre conocido por el algoritmo de antemano. Prestar especial atención a los siguientes
ejemplos, que describen el funcionamiento del algoritmo:
P Text (pred(suc 3), {pred, suc, 3}) = T otal ; ∅ ` pred(suc 3) : int
P Text (pred(suc 3), {pred}) = ∅ ` pred(suc 3) : int
P Text (pred(suc 3), {suc, 3}) = ∅ ` pred(suc 3) : int
P Text (5, {5}) = T otal ; ∅ ` 5 : int
P Text (x, {}) = {x : σ} ` x : σ
P Text (λx.suc x, {suc}) = ∅ ` (λx : int.suc x) : int → int
P Text (λx.suc, {suc}) = T otal ; ∅ ` (λx : σ.suc) : σ → int → int
Notar que la forma de inferir el tipo de un término para P T ext es exactamente la misma que la
de P T . También tener en cuenta que no solamente los sı́mbolos de función pueden pertenecer
a C, sino también las constantes (por ejemplo, los números naturales). Notar también que las
variables nunca son consideradas totales.
Ejercicio 2 - PCF
(25 puntos) Se quiere extender PCF para agregar la construcción either, que permite
representar la unión de varios tipos. Por ejemplo, la expresión:
2
either{nat,bool,bool→nat}
T rue
representa a un elemento que puede ser de tipo nat, de tipo bool, o de tipo función de bool en
nat. En este caso se lo está construyendo a partir de True, un booleano, que queda “encapsulado” por el constructor y que pasa a ser visto como un elemento de la unión de los tres tipos
antes mencionados. El superı́ndice indica con qué tipo efectivamente se está construyendo la
unión.
1
Para proyectar either se utiliza la construcción case, que recibe un término construido con
either y tantos términos adicionales como elementos tiene la unión. Por ejemplo:
2
case{nat,bool,bool−>nat,nat} (either{nat,bool,bool→nat}
T rue)(λx.x+1)(λx.if x then 0 else 1)(λx.x T rue)
es un término de tipo nat, que evalúa en 0.
Para soportar esta construcción, se pide extender el conjunto de pseudo términos, el conjunto
de tipos y las reglas de tipado de PCF. También se pide extender la semántica axiomática
con nuevas reglas para darle el significado apropiado.
Ejercicio 3 - Programación funcional
Tenemos a nuestra disposición el siguiente tipo de dato, que representa a un árbol binario:
1
data Arbol a = Hoja a | Bin a (Arbol a) (Arbol a)
2
Por ejemplo:
3
4
miArbol = Bin 1 (Hoja 2) (Bin 3 (Bin 4 (Hoja 6) (Hoja 7)) (Hoja 5))
miOtroArbol = Bin 4 (Bin 5 (Hoja 8) (Hoja 9)) (Hoja 7)
6
4
5
7
miArbol
5
8
7
9
miOtroArbol
Está definido también el siguiente esquema de recursión para operar con un Arbol y una lista
a la vez:
foldAL::(a->b)->(a->c->b)->(a->Arbol a->Arbol a->b)->(a->c->b->b->b)->Arbol a->[c]->b
foldAL f g h i (Hoja n) [] = f n
foldAL f g h i (Hoja n) (x:xs) = g n x
foldAL f g h i (Bin n ai ad) [] = h n ai ad
foldAL f g h i (Bin n ai ad) (x:xs) = i n x (foldAL f g h i ai xs) (foldAL f g h i ad xs)
Se pide definir las siguientes funciones, sin utilizar recursión explı́cita:
a) (5 puntos) Usando foldAL definir la función recorrido::Arbol a->[Bool]->[a], que devuelve la lista de nodos que se visitan siguiendo el recorrido determinado por las direcciones contenidas en la lista recibida como parámetro (True indica que se debe recorrer el
subárbol izquierdo y False el subárbol derecho) comenzando desde la raı́z.
Por ejemplo: recorrido miArbol [False, True] = [1,3,4]
recorrido miArbol [True, False, True] = [1,2]
b) (15 puntos) Redefinir el siguiente esquema de recursión tradicional de árboles:
foldA::(a->b)->(a->b->b->b)->Arbol a->b
foldA f g (Hoja n) = f n
foldA f g (Bin n sai sad) = g n (foldA f g sai) (foldA f g sad)
directamente en función del esquema de recursión foldAL.
c) (20 puntos) Usando foldAL definir la función aparear::Arbol a->[Int]->Arbol (a,Int),
que devuelve un árbol de pares en donde se reemplaza cada nodo de nivel i por un par cuya
primera componente es el valor del nodo original y la segunda componente es el i-ésimo
elemento de la lista recibida como parámetro. En caso de que no exista tal elemento en la
(4,10)
lista, la segunda componente debe ser -1.
Por ejemplo:
(5,20) (7,20)
(8,-1)
aparear miOtroArbol [10, 20] = miNuevoArbol
(9,-1)
miNuevoArbol
2
Descargar