Está en la página 1de 30

Evaluaci on Perezosa

Mauro Jaskelio

Lunes 26 de Octubre, 2011

Valores y Tipos

Hasta ahora hemos visto los tipos como conjuntos. Por ejemplo los elementos de Integer son los enteros . . . , 2, 1, 0, 1, 2, . . . Consideremos la siguiente expresi on innito :: Integer innito = innito + 1 La expresi on est a bien tipada. Qu e valor del tipo Integer denota innito ? :: Integer

Bottom

Para que toda expresi on tenga un valor en el tipo consideramos que cada tipo posee un valor llamado bottom (escribimos ).
representa el valor indenido.

Por ejemplo, una funci on que no termina devuelve . Notar que no podemos hacer una funci on que decida si su argumento es o no. Decimos que una funci on f es estricta si f = . siete x = 7 (no estricta) sqr x = x x (estricta)

Valores Parciales
El considerar el valor en un tipo algebraico signica que podemos tener valores parciales Listas Parciales 1: Arboles parciales data T = L Int | N T T N Tuplas parciales (, ) (, 4, ) N (L 3) 1:2:

Newtypes
Se puede declarar un nuevo tipo con un solo constructor con un solo argumento usando newtype newtype Par a b = MkPar (a, b ) A diferencia de type, se crea un nuevo tipo Par a b (a, b ) A diferencia de data, el constructor es estricto data Par a b = MkPar (a, b ) MkPar = MkPar

El newtype s olo existe durante la compilaci on. Por lo tanto es m as eciente en su uso de la memoria.

Ejercicios

Dar el valor de las siguientes expresiones:


1. fst (2, ) 2. snd (2, ) 3. x

Enumerar los elementos del tipo de datos Unit y evaluar cu al es el resultado al aplicarlos a f1 , f2 , y f3 . data Unit = Un () f1 x = Un () f2 (Un x ) = Un x f3 (Un ()) = Un () Cu ales de estas funciones son estrictas?

Inducci on Exhaustiva
Dado que podemos tener valores parciales debemos modicar las pruebas por inducci on Agregamos un caso base adicional. Debemos probar P () En este caso estamos realizando inducci on exhaustiva Por ejemplo, probamos xs + + (ys + + zs ) = (xs + + ys ) + + zs por inducci on sobre toda lista (nita o parcial) xs .
Ya hemos probado que la propiedad vale para [ ] y que si vale para xs vale para (x : xs ) Probamos que vale para : + + (ys + + zs ) = =+ + zs = ( + + ys ) + + zs

Otro Ejemplo

Probar reverse (xs + + ys ) = reverse ys + + reverse xs Por inducci on exhaustiva sobre xs . Los casos xs = [ ] y xs = (x : xs ) quedan como ejercicio. Veamos el caso reverse ( + + ys ) = reverse ys + + reverse LI reverse ( + + ys ) = reverse = LD reverse ys + + reverse = reverse ys + +

La propiedad no se cumple para valores parciales! Ejercicio: Probar que no se cumple con xs = e ys = [ 1, 2 ]

Estrategia de Evaluaci on
Al igual que en el -c alculo, tenemos diferentes estrategias de evaluaci on posibles CBV sqr (3 + 4) { def + } sqr 7 = { def sqr } 77 = { def } 49 = = CBN sqr (3 + 4) { def sqr } (3 + 4) (3 + 4) = { def + } 7 (3 + 4) = { def + } 77 = { def } 49

Dos estrategias diferentes siempre llegan al mismo resultado (si ambas terminan) Notar que esto no pasa en los lenguajes imperativos.

Terminaci on
Qu e pasa cuando uno de los dos no termina? CBV fst (0, innito ) = { def innito } fst (0, innito + 1) = fst (0, (innito + 1) + 1) = . . . CBN fst (0, innito ) = { def fst } 0

La estrategia de reducci on normal encuentra un valor denido (si lo hay)

Cantidad de Reducciones
La cantidad de reducciones var a seg un la estrategia de evaluaci on CBV = fst (sqr 4, sqr 2) { def sqr } fst (4 4, sqr 2) = { def } fst (16, sqr 2) = { def sqr } fst (16, 2 2) = { def } fst (16, 4) = { def fst } 16 = CBN fst (sqr 4, sqr 2) { def fst } sqr 4 = { def } 44 = { def sqr } 16

En este caso CBN es mas eciente

Cantidad de Reducciones
La cantidad de reducciones var a seg un la estrategia de evaluaci on CBV sqr (3 + 4) { def + } sqr 7 = { def sqr } 77 = { def } 49 = = CBN sqr (3 + 4) { def sqr } (3 + 4) (3 + 4) = { def + } 7 (3 + 4) = { def + } 77 = { def } 49

en este caso CBV es m as eciente.

Reducci on de grafos
En el u ltimo ejemplo CBV es m as eciente porque sqr duplica su argumento. Se puede mejorar la estrategia CBN utilizando grafos en lugar de arboles. sqr (3 + 4) { def sqr }

= { def + } = { def } 49
@

ED

(3 + 4) 7

Esta t ecnica se denomina reducci on de grafos.

Evaluaci on Perezosa

Esta estrategia de evaluaci on (CBN + reducci on de grafos) se denomina evaluaci on perezosa. Un argumento se eval ua s olo si es necesario. Incluso si el argumento es necesario, no necesariamente se eval ua por completo (ej: pattern matching). Si un argumento se eval ua s olo se eval ua una u nica vez. La evaluaci on perezosa da lugar a que deniciones aparentemente inecientes no lo sean.

Un poco de magia
Consideremos insertion sort iSort :: Ord a [ a ] [ a ] iSort [ ] = [] iSort (x : xs ) = ins x (iSort xs ) ins :: (Ord t ) t [ t ] [ t ] ins x [ ] = [x ] ins x (y : ys ) | x y = x : (y : ys ) | otherwise = y : ins x ys Queremos encontrar el m nimo de una lista. Ser a eciente la siguiente funci on? minimo xs = head (iSort xs )

Un poco de magia (cont.)

Veamos la reducci on de minimo [ 8, 6, 1, 7, 5 ] minimo [ 8, 6, 1, 7, 5 ] head (iSort [ 8, 6, 1, 7, 5 ]) head (ins 8 (ins 6 (ins 1 (ins 7 (ins 5 [ ]))))) head (ins 8 (ins 6 (ins 1 (ins 7 [ 5 ])))) head (ins 8 (ins 6 (ins 1 (5 : ins 7 [ ])))) head (ins 8 (ins 6 (1 : (5 : ins 7 [ ])))) head (ins 8 (1 : ins 6 (5 : ins 7 [ ]))) head (1 : ins 8 (ins 6 (5 : ins 7 [ ]))) 1 La funci on es lineal!

Listas Innitas
La evaluaci on perezosa permite trabajar con estructuras innitas. Ejemplo unos :: [ Int ] unos = 1 : unos unos { def unos } 1 : unos = { def unos } 1 : 1 : unos = { def unos } 1 : 1 : 1 : unos . . . =

Criba de Erat ostenes


Algoritmo para encontrar todos los n umeros primos.
1. 2. 3. 4. Escribir la secuencia 2, 3, 4 ,5 ,6, . . . Marcar el primer n umero, p , en la secuencia como primo Borrar de la secuencia todos los m ultiplos de p Volver al paso 2

En principio el paso 1 y 3 llevan un tiempo innito En Haskell lo escribimos: primos :: [ Int ] primos = cribar [ 2 . . ] cribar :: [ Int ] [ Int ] cribar (p : xs ) = p : cribar [ x | x xs , x mod p 0 ]

Separando Datos y Control

Si ejecutamos > primos [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, . . . > take 10 primos [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ] > takeWhile (<10) primos [ 2, 3, 5, 7 ] En la pr actica s olo usamos un n umero nito de primos
Qu e ganamos?

Ganamos modularidad: separamos la generaci on de los datos del control de los mismos.

Listas de exitos

Una t ecnica com un para hacer backtracking en lenguajes perezosos es la lista de exitos. En lugar de buscar una respuesta, generamos una lista con todas las respuestas. La lista vac a se nala la ausencia de respuestas. Si la lista es no vac a, podemos tomar la cabeza de la misma para obtener una respuesta. La evaluaci on perezosa se encarga de que no se haga m as trabajo que lo necesario.

Caminos en un Grafo
Queremos encontrar un camino de un v ertice a otro en un digrafo ac clico. Para eso, encontramos todos los caminos. type Grafo a = [(a, a)] caminos :: Eq a Grafo a a a [[ a ]] caminos g x y | x y = [[ x ]] | otherwise = [ x : r | z vecinos g x , r caminos g z y ] vecinos :: Eq a Grafo a a [ a ] = [] vecinos [ ] vecinos ((a, b ) : xs ) x | x a = b : vecinos xs x | otherwise = vecinos xs x

Caminos en un Grafo (cont.)

1


G3 G4

G5 0 

g = [(1, 2), (1, 3), (2, 4), (3, 5), (5, 6), (3, 6)]

caminos g 1 6 [ 1 : r | z vecinos g 1, r caminos g z 6 ] [ 1 : r | z [ 2, 3 ], r caminos g z 6 ] [ 1 : r | r caminos g 2 6 ] + + [ 1 : r | r caminos g 3 6 ] [] + + [ 1 : r | r caminos g 3 6 ] [ 1 : r | r [ 3 : s caminos g 5 6 ]] + + ... [[ 1, 3, 5, 6 ]] + + ... El efecto de la lista de exitos es backtracking ante una falla.

Sharing
El modelo de reducci on por grafos permite la programaci on circular Ya vimos un ejemplo simple ones = 1 : ones que corresponde con el grafo 1 : Otro cl asico ejemplo es el siguiente: data Tree = Leaf Int | Node Tree Tree Queremos reemplazar todas las hojas de un arbol por su valor m nimo. Queremos hacerlo en una sola pasada!

Reemplazo del M nimo (2 recorridos)

Considere el siguiente programa transform :: Tree Tree transform t = rep t (tmin t ) tmin :: Tree Int tmin (Leaf n) = n tmin (Node l r ) = tmin l min tmin r rep :: Tree Int Tree rep (Leaf ) n = Leaf n rep (Node l r ) n = Node (rep l n) (rep r n) El a rbol se recorre dos veces.

Mejorando repmin
C omo implementar transform en una sola pasada? A medida que recorremos el arbol reemplazamos los valores en las hojas por el valor min mo que calcularemos en el futuro. Gracias a la evaluaci on perezosa podemos denir: trace :: ((i , feedback ) (o , feedback )) i o trace f i = o where (o , z ) = f (i , z )
i z f o z

Estamos usando el valor z del resultado como argumento!

Reemplazo del m nimo (1 recorrido)

Para resolver nuestro problema necesitamos una funci on con la siguiente especicaci on repmin :: (Tree , Int ) (Tree , Int ) repmin (t , m) = (rep t m, tmin t ) Calculamos: El caso Leaf es: repmin (Leaf n, m) = (rep (Leaf n) m, tmin (Leaf n)) = (Leaf m, n)

C alculo de repmin

Especicaci on: repmin (t , m) = (rep t m, tmin t ) El caso Node : repmin (Node l r , m) = (rep (Node l r ) m, tmin (Node l r )) = (Node (rep l m) (rep r m), tmin l min tmin r ) = (Node l r , nl min nr ) where (l , nl ) = (rep l m, tmin l ) (r , nr ) = (rep r m, tmin r ) = (Node l r , nl min nr ) where (l , nl ) = repmin l m (r , nr ) = repmin r m

Soluci on en un recorrido

Acabamos de calcular la siguiente funci on: repmin :: (Tree , Int ) (Tree , Int ) repmin (Leaf n, m) = (Leaf m, n) repmin (Node l r , m) = (Node l r , nl min nr ) where (l , nl ) = repmin (l , m) (r , nr ) = repmin (r , m) La soluci on en un recorrido es: transform :: Tree Tree transform = trace repmin

Resumen

Todo tipo tiene un valor . Los tipos pueden tener valores parciales. La inducci on debe ser extendida para manejar este caso. La evaluaci on perezosa facilita algunos estilos de programaci on:
Separaci on de Datos y Control Listas de Exitos Programaci on Circular

Referencias

Programming in Haskell. Graham Hutton (2007) Introduction to Functional Programming. Richard Bird (1998) Using circular programs to eliminate multiple traversals of data. Richard Bird. Acta Informatica 1984.

También podría gustarte