Compilaci ó n de Pattern Matching

20
1 Compilación de Pattern Matching Un ejemplo: zipWith f [] ys = [] zipWith f (x:xs) [] = [] zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys Semántica de pattern matching Se asume: (1) testea cada ecuación por un match top to bottom (2) Para cada ecuación, testea cada pattern por un match de izquierda a derecha, si falla termina con esa ecuación y testea la siguiente. Traduccion en expresiones case simples: una secuencia eficiente de tests, testeando cada valor sólo una vez

description

Compilaci ó n de Pattern Matching. Un ejemplo: zipWith f [] ys = [] zipWith f (x:xs) [] = [] zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys Semántica de pattern matching Se asume: (1) testea cada ecuación por un match top to bottom - PowerPoint PPT Presentation

Transcript of Compilaci ó n de Pattern Matching

Page 1: Compilaci ó n de Pattern Matching

1

Compilación de Pattern Matching

Un ejemplo:

zipWith f [] ys = [] zipWith f (x:xs) [] = [] zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys

Semántica de pattern matching Se asume:(1) testea cada ecuación por un match top to bottom(2) Para cada ecuación, testea cada pattern por un match de izquierda a derecha,

si falla termina con esa ecuación y testea la siguiente.

Traduccion en expresiones case simples: una secuencia eficiente de tests, testeando cada valor sólo una vez

Page 2: Compilaci ó n de Pattern Matching

2

Expresiones case simples

zipWith = \ f xs' ys -> case xs' of Nil -> Nil Cons x xs -> case ys' of Nil -> Nil Cons y ys -> Cons (f x y) (zipWith f xs ys)

case e of C1 v11 ... v1k1 -> e1

... Cn vn1 ... vnkn -> en v -> e

. Sub-patterns son simple variables (vij's).

. default pattern v -> e es opcional.

Page 3: Compilaci ó n de Pattern Matching

3

Traducción

f p11 ...p1n = e1...f pm1 ...p mn = em

f = \ u1 ...un -> ( (( \ (p11’ ,..., p1n’) -> e1’) u1...un )(( \ (pm1’ ,..., pmn’) -> em’) u1...un )ERROR )

Nuestro objetivo entonces es transformar una expresión de esta forma en una expresión equivalente definida en función de expresiones case.

Page 4: Compilaci ó n de Pattern Matching

4

La función match

match [ u 1 , ..., u n ] [([ p11 , ..., p1n ] , [e1]) , ([ pm1 , ..., pmn ] , [em]) ] [ error "no match in f"]

match us qs e, donde us: una lista de variables a ser testeadas por un match, qs: una lista de ecuaciones, e: expresion por defecto, si ninguna ecuacion en qs machea entonces e es el valor retornado

Page 5: Compilaci ó n de Pattern Matching

5

Un ejemplo de corrida: demo

demo f [] ys = aa f ysdemo f (x:xs) [] = bb f x xs demo f (x:xs) (y:ys) = cc f x xs y ys

demo = \ u1 u2 u3 -> match [ u1 , u2 , u 3] [( [f , Nil , ys ] , [ aa f ys ]) , ( [f , Cons x xs , Nil ] , [ bb f x xs]) , ( [f , Cons x xs ,Cons y ys ] ,[cc f x xs y ys ]) ] [ error "no match in demo"]

Page 6: Compilaci ó n de Pattern Matching

6

La regla de la Variabledemo = \ u1 u2 u3 -> match [ u1 , u2 , u3] [( [f , Nil , ys ] ,[ aa f ys ]) , ( [f , Cons x xs ,Nil ] ,[ bb f x xs]) , ( [f , Cons x xs ,Cons y ys ] ,[cc f x xs y ys ]) ] [ error "no match in demo"]

Todos los primer patterns son variables

demo = \ u1 u2 u3 -> match [u2 , u3] [ ( Nil , ys ] , [ aa f ys ]) , ( Cons x xs , Nil ] , [ bb f x xs]) , ( Cons x xs , Cons y ys ] , [cc f x xs y ys ]) ] [ error "no match in demo"] Nota: Las variables no necesitan ser las mismas

Page 7: Compilaci ó n de Pattern Matching

7

Regla 2: la regla Constructor

Todos los primer patterns son constructores ejemplo: en un data type que incluye constructores A, B y C. match ([ u ] : us ) [([ A psa1 ]: ps'a1, ea1 ), ([ B psb1 ]: ps'b1, eb1 ), ([ A psa2 ]: ps'a2, ea2 ), ([ B psb2 ]: ps'b2, eb2 ), ([ C psc1 ]: ps'c1, ec1 ), ([ A psa3 ]: ps'a3, ea3 ) ] d=>

Page 8: Compilaci ó n de Pattern Matching

8

Regla 2 (cont.)case u of A us'a -> match ( us'a ++ us ) [ ( psa1 ++ ps'a1 , ea1 ), ( psa2 ++ ps'a2 , ea2 ), ( psa3 ++ ps'a3 , ea3 )] d

B us'b -> match ( us'b ++ us ) [ ( psb1 ++ ps'b1 , eb1 ), ( psb2 ++ ps'b2 , eb2 )] d

C us'c -> match ( us'c ++ us ) [ ( psc1 ++ ps'c1 , ec1 )] d u' -> d

Page 9: Compilaci ó n de Pattern Matching

9

Una nota sobre el orden de ecuaciones

match ([ u ] : us ) [([ A psa1 ]: ps'a1, ea1 ), ([ B psb1 ]: ps'b1, eb1 ), ([ A psa2 ]: ps'a2, ea2 ), ([ B psb2 ]: ps'b2, eb2 ), ([ C psc1 ]: ps'c1, ec1 ), ([ A psa3 ]: ps'a3, ea3 ) ] d=>

match ([ u ] : us ) [([ A psa1 ]: ps'a1, ea1 ), ([ A psa2 ]: ps'a2, ea2 ), ([ A psa3 ]: ps'a3, ea3 ) ([ B psb1 ]: ps'b1, eb1 ), ([ B psb2 ]: ps'b2, eb2 ), ([ C psc1 ]: ps'c1, ec1 ), ] d

Es siempre seguro permutar ecuaciones adyacentes con diferentes constructores. Entonces, en general se podría ordenar la lista con clave el constructor usando un sort estable.

Page 10: Compilaci ó n de Pattern Matching

10

Usando la regla 2Los primeros patterns son constructores

demo = \ u1 u2 u3 -> case u2 of Nil -> match [u3] [( [ ys ] , [ aa u1 ys]) ] [ error "no match in demo"] Cons u4 u5 -> match [u4, u5, u3] [ ( [ x xs , Nil ] , [ bb u1 x xs]) , ( [ x xs , Cons y ys ] , [ cc u1 x xs y ys ]) ] [ error "no match in demo"]

v -> [ error "no match in demo"]

Page 11: Compilaci ó n de Pattern Matching

11

Regla 2 (cont.)demo = \ u1 u2 u3 -> case u2 of Nil -> match [u3] [( [ ys ] , [ aa u1 ys]) ] [ error "no match in demo"] Cons u4 u5 -> match [u4, u5, u3] [ ( [ x xs , Nil ] , [ bb u1 x xs]) , ( [ x xs , Cons y ys ] , [ cc u1 x xs y ys ]) ] [ error "no match in demo"]

v -> [ error "no match in demo"]

Aplicamos la regla de variable 3 veces

Page 12: Compilaci ó n de Pattern Matching

12

Regla 2 (cont.)demo = \ u1 u2 u3 -> case u2 of Nil -> match [ ] [( [ ] , [ aa u1 u3]) ] [ error "no match in demo"] Cons u4 u5 -> match [ u3 ] [ ( [ Nil ] , [ bb u1 u4 u5]) , ( [ Cons y ys ] , [ cc u1 u4 u5 y ys ]) ] [ error "no match in demo"]

v -> [ error "no match in demo"]

Regla 3:la regla Vacía

match [] [([] , e1 )] ... [([] , em )] d => e1 … …em…d

Page 13: Compilaci ó n de Pattern Matching

13

demo (cont.)

demo = \ u1 u2 u3 -> case u2 of Nil -> aa u1 u3 Cons u4 u5 -> case u3 of Nil -> match [ ] [([ ] , [ bb u1 u4 u5])] [ error "no match in demo"] Cons u6 u7 -> match [ ] [([ ] , [ cc u1 u4 u5 u6 u7])] [ error "no match in demo"] v -> [ error "no match in demo"]

v -> [ error "no match in demo"]

Page 14: Compilaci ó n de Pattern Matching

14

... y finalmentedemo = \ u1 u2 u3 -> case u2 of Nil -> aa u1 u3 Cons u4 u5 -> case u3 of Nil -> bb u1 u4 u5 Cons u6 u7 -> cc u1 u4 u5 u6 u7 v -> [ error "no match in demo"]

v -> [ error "no match in demo"]

Si todos los constructores de un data type están presentes en el case, entonces el caso por defecto puede ser eliminado.

Page 15: Compilaci ó n de Pattern Matching

15

demo’: otra versión de demo

demo' f [] ys = aa f ysdemo' f xs [] = bb f x xs demo' f (x:xs) (y:ys) = cc f x xs y ys

=>

demo' = \ u1 u2 u3 -> match [ u1 , u2 , u3] [ ( [ f , Nil , ys ] , [ aa f ys ]) , ( [ f , xs , Nil ] , [ bb f x xs]) , ( [ f , Cons x xs , Cons y ys ] , [cc f x xs y ys ]) ] [ error "no match in demo"]

Page 16: Compilaci ó n de Pattern Matching

16

demo’ (2)

demo' = \ u1 u2 u3 -> match [ u2 , u3] [ ( [ Nil , ys ] , [ aa u1 ys ]) , ( [ xs , Nil ] , [ bb u1 x xs]) , ( [ Cons x xs ,Cons y ys ] , [cc u1 x xs y ys ]) ] [ error "no match in demo"]

Los primer patterns no son enteramente variables ni enteramente constructores.

Page 17: Compilaci ó n de Pattern Matching

17

Regla 4: la regla Mixta

match us qs d

donde los primer patterns en qs no son enteramente variables ni enteramente constructores.

Efectuamos una partición de qs en k listas

qs = qs1 ++ qs2 ++ ... ++ qsk

tal que los primer patterns de cada qsi son todos variables o todos constructores.

Entonces match us qs d = match us qs1 (match us qs2 (...(match us qsk d)...))

Nota: la regla mixta siempre puede ser aplicada, pero su uso es sólo necesario en el caso de primer patterns mezclados.

Page 18: Compilaci ó n de Pattern Matching

18

demo’ (cont.)

demo' = \ u1 u2 u3 -> match [ u2 , u3] [ ( [ Nil , ys ] , [ aa u1 ys ]) ] ( match [ u2 , u3] [ ( [ xs , Nil ] , [ bb u1 x xs])] ( match [ u2 , u3] [ ( [ Cons x xs ,Cons y ys ] , [cc u1 x xs y ys ]) ] [ error "no match in demo"] ))

Deficiencias: La regla mixta fácilmente causa que la misma variable sea examinada más de una vez. Esto puede ser optimizado en una pasada posterior.

Page 19: Compilaci ó n de Pattern Matching

19

Completitud

Ahora es posible reducir toda posible llamada a match a una expresión case. Podemos razonar haciendo un simple análisis de casos.

Dada una aplicación (match us qs e) :

• si us es [] entonces aplicamos la regla Vacía• sino, entonces cada ecuación debe contener una lista no vacía de patrones, la que debe empezar o con una variable o con un constructor.

• si todos son variables => se aplica la regla Variable• si todos son constructores => se aplica la regla Constructor• sino => se aplica la regla Mixta

Page 20: Compilaci ó n de Pattern Matching

20

Terminacióndata Pattern = Var Vars | Cons Const [Pattern]type Vars = Stringtype Const = String

type Eq = ([ Pattern ] , Exp)type Eqs = [Eq]

sizeeqs :: Eqs -> Int

Se puede demostrar fácilmente que para las cuatro reglas que definimos las llamadas recursivas a match son efectuadas sobre listas de ecuaciones de menor tamaño. Esto garantiza que el algoritmo termina.