La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

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.

Presentaciones similares


Presentación del tema: "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."— Transcripción de la presentación:

1

2 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

3 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 C 1 v 11... v 1k1 -> e 1... C n v n1... v nkn -> e n v -> e. Sub-patterns son simple variables (v ij 's).. default pattern v -> e es opcional.

4 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.

5 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

6 5 Un ejemplo de corrida: demo demo f [] ys = aa f ys demo 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"]

7 6 La regla de la Variable demo = \ 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

8 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 =>

9 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

10 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.

11 10 Usando la regla 2 Los 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"]

12 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

13 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 [] [([], e 1 )]... [([], e m )] d => e 1    …  e m  d

14 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"]

15 14... y finalmente demo = \ 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"] Si todos los constructores de un data type están presentes en el case, entonces el caso por defecto puede ser eliminado.

16 15 demo’: otra versión de demo demo' f [] ys = aa f ys demo' 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"]

17 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.

18 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.

19 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.

20 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

21 20 Terminación data Pattern = Var Vars | Cons Const [Pattern] type Vars = String type 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.


Descargar ppt "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."

Presentaciones similares


Anuncios Google