Sistemas de tipos en programación...

Post on 20-Jan-2020

7 views 0 download

Transcript of Sistemas de tipos en programación...

Enrique Martín MartínTesis Doctoral

Directores: Francisco J. López Fraguas

Juan Rodríguez Hortalá

Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid

6 de julio de 2012

Sistemas de tipos en programación lógico-funcional

Contexto de la tesis

Programación lógico-funcional: integración de los dos principales paradigmas de programación declarativa.

Sistemas: Curry (PAKCS, Münster, KICS), Toy.

Programación lógica

Búsqueda indeterminista Variables lógicas

PROGRAMACIÓN LÓGICO-FUNCIONAL

Programación funcional

Funciones de orden superior Polimorfismo Damas-Milner Evaluación perezosa

Ejemplo de programa Toy

data nat = zero | succ nat

coin :: nat dup :: A -> (A,A)coin = zero dup X = (X,X)coin = succ zero

last :: [A] -> Alast Xs = if (Xs == Zs ++ [E]) then E

f :: ([A] -> A) -> boolf last = true

Ejemplo de programa Toy

data nat = zero | succ nat

coin :: nat dup :: A -> (A,A)coin = zero dup X = (X,X)coin = succ zero

last :: [A] -> Alast Xs = if (Xs == Zs ++ [E]) then E

f :: ([A] -> A) -> boolf last = trueFunciones indeterministas

Toy> coin == R { R -> zero }sol.1, more solutions (y/n/d/a) [y]? y { R -> (succ zero) } sol.2, more solutions (y/n/d/a) [y]? y no

Ejemplo de programa Toy

data nat = zero | succ nat

coin :: nat dup :: A -> (A,A)coin = zero dup X = (X,X)coin = succ zero

last :: [A] -> Alast Xs = if (Xs == Zs ++ [E]) then E

f :: ([A] -> A) -> boolf last = true

call-time choicelas copias de expresiones indeterministasrealizadas durante el paso de parámetros

comparten el mismo valor

Toy> dup coin == R { R -> (zero, zero) } sol.1, more solutions (y/n/d/a) [y]? y { R -> ((succ zero), (succ zero)) } sol.2, more solutions (y/n/d/a) [y]? y no

Ejemplo de programa Toy

data nat = zero | succ nat

coin :: nat dup :: A -> (A,A)coin = zero dup X = (X,X)coin = succ zero

last :: [A] -> Alast Xs = if (Xs == Zs ++ [E]) then E

f :: ([A] -> A) -> boolf last = true

Variables extras en las reglas(variables que solo aparecen en

el lado derecho)

Toy> last [] == R noToy> last [true, false] == R { R -> false }

Ejemplo de programa Toy

data nat = zero | succ nat

coin :: nat dup :: A -> (A,A)coin = zero dup X = (X,X)coin = succ zero

last :: [A] -> Alast Xs = if (Xs == Zs ++ [E]) then E

f :: ([A] -> A) -> boolf last = true

Patrones de orden superior(last tiene aridad 1)

Toy> f last == R { R -> true } Toy> f head == R no

Aplicaciones parciales deconstructoras o símbolos de función.

Al igual que las constructorascompletamente aplicadas, son valores.

Pueden aparecer en los ladosizquierdos de las reglas.

Permiten distinguir de maneraintensional distintas descripcionesde una misma función extensional.

Contexto de la tesis

Los lenguajes lógico-funcionales heredan directamente el sistema de tipos de Damas-Milner (DM) utilizado en programación funcional: Haskell, ML.

Ventajas: tipos principales, algoritmo de inferencia eficente.

PROBLEMAS de Damas-Milner

NO considera patrones de orden superior.

NO considera variables libres(estrechamiento).

Objetivo principal

Proponer sistemas de tipos para los lenguajeslógico-funcionales que manejen adecuadamentesus características (patrones de orden superior,

variables libres, etc.), evitando así los problemas queaparecen utilizando una adaptación directa de DM.

Objetivo I

Manejar adecuadamente los patrones de orden superior

Este programa está bien tipado utilizando Damas-Milner.

Sin embargo no preserva tipos:

not (cast zero) tiene tipo bool, ya que cast zero puede tener cualquier tipo.

Sin embargo, not zero no admite ningún tipo.

snd :: A -> B -> B unpack :: (A -> A) -> Bsnd X Y = Y unpack (snd X) = X

cast :: A -> B not :: bool -> boolcast X = unpack (snd X) not true = false

not false = true

Objetivo II

Conseguir un sistema de tipos para PLF más relajado, que siga garantizando la preservación de tipos.

Este programa está mal tipado utilizando Damas-Milner, sin embargo no viola la preservación de tipos.

Un sistema de tipos que aceptase esta función tendría interesantes posibilidades para la programación genérica.

size :: A -> natsize true = succ zerosize false = succ zerosize zero = succ zerosize (succ X) = succ (size X)size [] = succ zerosize (X:Xs) = succ (add (size X) (size Xs))

Objetivo III

Manejar adecuadamente el problema de la descomposición opaca

Los sistemas de PLF utilizan una igualdad estructural (==) predefinida de tipo A -> A -> bool que no podría definirse mediante reglas ya que estas estarían mal tipadas.

En presencia de patrones de orden superior, la igualdad estructural puede generar pasos de descomposición que no preservan los tipos:

(snd true) == (snd zero) está bien tipada.

Sin embargo, true == zero no admite ningún tipo.

snd :: A -> B -> Bsnd X Y = Y

Objetivo IV

Manejar las variables libres y extras, garantizando la preservación de tipos con estrechamiento

Las ligaduras generadas al evaluar (utilizando estrechamiento) pueden generar problemas de tipos de manera muy sencilla:

succ (F zero) tienen tipo nat cuando F tiene tipo nat -> nat, sin embargo, succ false no admite ningún tipo.

[f (snd X), X] tiene tipo [bool] cuando X tiene tipo bool, sin embargo, [true, zero] no admite ningún tipo.

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

Organización

1.Sistema de tipos con manejo seguro de patrones de orden superior

2.Sistema de tipos liberal

3.Aplicación del sistema de tipos liberal a la traducción de clases de tipos en PLF

4.Sistema de tipos con soporte para variables libres/extra y estrechamiento

5.Conclusiones

1.Sistema de tipos con manejo seguro de patrones de orden superior

2.Sistema de tipos liberal

3.Aplicación del sistema de tipos liberal a la traducción de clases de tipos en PLF

4.Sistema de tipos con soporte para variables libres/extra y estrechamiento

5.Conclusiones

Patrones de orden superior

¿Por qué causan problemas de tipos? Porque, a diferencia de los patrones de primer orden (aplicaciones

totales de símbolos de constructora), el tipo del patrón completo puede no determinar unívocamente el tipo de sus componentes.

Por ejemplo, saber que (snd X) tiene tipo A->A no nos indica el tipo de X, que podría ser cualquiera: bool, nat, [bool -> nat]...

Una adaptación directa de DM trata esta “opacidad ” comopolimorfismo, y es por ello que infiere el tipo (A->A)->Bpara la función unpack (donde B es el tipo de X desconocido).

snd :: A -> B -> B unpack :: (A -> A) -> Bsnd X Y = Y unpack (snd X) = X

Patrones de orden superior

¿Cómo solucionarlo?

a) Hacer una distinción entre variables transparentes y opacas de un patrón:

Una variable de datos X es opaca en un patrón t si su tipo no está unívocamente determinado por el tipo del patrón.

Si el tipo de X sí está unívocamente determinado por el tipo de t, dicha variable de datos es transparente.

b) Se prohíbe la aparición de variables críticas, esto es, variables opacas en los lados derechos de las reglas y en el cuerpo de λ-abstracciones y let-expresiones.

Ejemplo: La variable X es opaca en el patrón (snd X) y por tantocrítica en la regla unpack (snd X) = X, que sería rechazada.

Formalización del sistema de tipos

Hemos divido la tarea de derivar tipo para una expresión en dos:

a)Derivación de tipos básicaEs similar a Damas-Milner pero considerando la aparición de patrones compuestos en λ-abstracciones y let-expresiones (y distintos grados de polimorfismo en let-expresiones)

b)Derivación de tipos extendidaUtiliza la derivación anterior y comprueba que no aparecen variables críticas

Derivación de tipos básica

Derivación de tipos básica

Iguales que Damas-Milner

Derivación de tipos básica

Inventa suposiciones para las variables del patrón t y deriva su tipo.

Utiliza esas mismas suposiciones para derivar el tipo de e.

Derivación de tipos básica

Inventa suposiciones para las variables del patrón t y deriva su tipo

Debe derivar el mismo tipo para la expresión ligada.

Usa esas suposiciones para derivar el tipo de e

2.

Soportamos 2 tipos más de polimorfismo en let-expresiones

Derivación de tipos extendida

Una variable es opaca en un patrón si

X es opaca en snd X:

X no es opaca en snd [true,X]:

Una variable es crítica si es opaca en el patrón de una let-expresión o λ-abstracción y aparece en el resto de la expresión.

Derivación de tipos extendida

Una variable es opaca en un patrón si

X es opaca en snd X:

X no es opaca en snd [true,X]:

Una variable es crítica si es opaca en el patrón de una let-expresión o λ-abstracción y aparece en el resto de la expresión.

Variables críticas de una expresión

Inferencia de tipos

Siguiendo las mismas ideas que la inferencia Damas-Milner: usar variables frescas y unificación.

Corrección:

Completitud : Si entonces tal que

Maximalidad : Si y entonces tal que

Preservación de tipos

Solo se garantiza para programas bien tipados.

Un programa está bien tipado si cada regla cumple:

Utiliza la semántica de let-reescritura [López-Fraguas et al.,2008]. Por tanto no considera estrechamiento ni variables libres/extra.

Preservación de tipos

Ejemplo: casting polimórfico

snd :: A -> B -> B unpack :: (A -> A) -> Bsnd X Y = Y unpack (snd X) = X

cast :: A -> B not :: bool -> boolcast X = unpack (snd X) not true = false

not false = true X es una variable opacaen el patrón snd X

X es crítica porqueaparece en el ladoderecho de la regla

Por tanto, la regla de unpack está mal tipada

1.Sistema de tipos con manejo seguro de patrones de orden superior

2.Sistema de tipos liberal

3.Aplicación del sistema de tipos liberal a la traducción de clases de tipos en PLF

4.Sistema de tipos con soporte para variables libres/extra y estrechamiento

5.Conclusiones

Motivación del sistema liberal

El sistema de tipos anterior ofrece algunas posibilidades limitadas para la programación genérica:

(nótese que no hay variables críticas, pues X está forzado a tener tipo nat)

La función code recibe argumentos de diferentes tipos encapsulados en un patrón opaco, que son inspeccionados

Sin embargo, no produce ningún error de tipos durante la ejecución

data bit = i | o data cont where cont :: A -> cont

code :: cont -> [bit] code (cont true) = [o,o,o] code (cont false) = [o,o,i]code (cont zero) = [o,i,o] code (cont (succ X)) = [o,i,i] ++ code (cont X)

Motivación del sistema liberal

¿Se podría ampliar la liberalidad sin perder la preservación de tipos?

Este programa es similar al anterior pero sería rechazado porque los tipos de sus reglas son incompatibles:

size :: bool -> nat

size :: nat -> nat

size :: [A] -> nat

Sin embargo, sigue sin producir errores de tipos.

size :: A -> nat

size true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

Motivación del sistema liberal

¿Se podría ampliar la liberalidad sin perder la preservación de tipos?

Este programa es similar al anterior pero sería rechazado porque los tipos de sus reglas son incompatibles:

size :: bool -> nat

size :: nat -> nat

size :: [A] -> nat

Sin embargo, sigue sin producir errores de tipos.

size :: A -> nat

size true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

Motivación del sistema liberal

¿Se podría ampliar la liberalidad sin perder la preservación de tipos?

Este programa es similar al anterior pero sería rechazado porque los tipos de sus reglas son incompatibles:

size :: bool -> nat

size :: nat -> nat

size :: [A] -> nat

Sin embargo, sigue sin producir errores de tipos.

size :: A -> nat

size true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

Motivación del sistema liberal

¿Se podría ampliar la liberalidad sin perder la preservación de tipos?

Este programa es similar al anterior pero sería rechazado porque los tipos de sus reglas son incompatibles:

size :: bool -> nat

size :: nat -> nat

size :: [A] -> nat

Sin embargo, sigue sin producir errores de tipos.

size :: A -> nat

size true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

Motivación del sistema liberal

¿Se podría ampliar la liberalidad sin perder la preservación de tipos?

Este programa es similar al anterior pero sería rechazado porque los tipos de sus reglas son incompatibles:

size :: bool -> nat

size :: nat -> nat

size :: [A] -> nat

Sin embargo, sigue sin producir errores de tipos.

size :: A -> nat

size true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

Objetivos del sistema liberal

Desarrollar un sistema de tipos para PLF con el grado más alto de liberalidad posible que siga garantizando la preservación de tipos.

Como semántica consideraremos la let-reescritura, por tanto el estrechamiento y las variables libres/extra no estarán permitidas.

Noción de programa bien tipado

Muy sencilla: Basada en la derivación básica presentada anteriormente

Requiere la declaración de tipos de todas las constructoras y símbolos de función

Regla a regla, sin importar el orden

Una regla de programa está bien tipada si:

a) admiten tipo

b) El tipo más general de e y sus variables es más general que aquellos para el lado izquierdo

Intuición: una regla está bien tipada si el lado derecho no fuerza los tipos más que

el lado izquierdo

Ejemplo: size

size :: A -> natsize true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

Ejemplo: size

size :: A -> natsize true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

size true :: nat succ zero :: nat

Ejemplo: size

size :: A -> natsize true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

size (succ X) :: natX :: nat

succ (size X) :: natX :: A

(nat, A) es más general que (nat, nat)

Ejemplo: size

size :: A -> natsize true = succ zero size false = succ zerosize zero = succ zero size (succ X) = succ (size X)size [] = succ zero size (X:Xs) = succ (add (size X) (size Xs))

size (X:Xs) :: natX :: A

Xs :: [A]

succ (add (size X) (size Xs)) :: natX :: BXs :: C

(nat, B, C) es más general que (nat, A, [A])

Ejemplo: casting polimórfico

snd :: A -> B -> B unpack :: (A -> A) -> Bsnd X Y = Y unpack (snd X) = X

cast :: A -> B not :: bool -> boolcast X = unpack (snd X) not true = false

not false = true

Ejemplo: casting polimórfico

snd :: A -> B -> B unpack :: (A -> A) -> Bsnd X Y = Y unpack (snd X) = X

cast :: A -> B not :: bool -> boolcast X = unpack (snd X) not true = false

not false = trueunpack (snd X) :: BX :: A

X :: C

Mal tipada porque (C,C) no es más general que (B,A)

Propiedades del sistema liberal

Preservación de tipos:

Propiedades del sistema liberal

Máxima liberalidad:Si en una regla de programa el lado derecho fuerza los tipos más que el izquierdo entonces:

Si una regla no está bien tipada sepuede construir una derivación que

rompe la preservación de tipos

Propiedades del sistema liberal

Máxima liberalidad:Si en una regla de programa el lado derecho fuerza los tipos más que el izquierdo entonces:

Equivalencia con reglas que preservan tipos:

Propiedades del sistema liberal

Máxima liberalidad:Si en una regla de programa el lado derecho fuerza los tipos más que el izquierdo entonces:

Equivalencia con reglas que preservan tipos:

Para cualquier tipo existe un patrón queúnicamente puede tener dicho tipo.

Al aplicar la regla con cualquier instancia desus argumentos se preserva el tipo.

Posibilidades del sistema liberal

Manejo adecuado de la opacidad generada por los patrones de orden superior

snd :: A -> B -> B unpack :: (A -> A) -> Bsnd X Y = Y unpack (snd X) = X

cast :: A -> B not :: bool -> boolcast X = unpack (snd X) not true = false

not false = trueunpack (snd X) :: BX :: A

X :: C

Mal tipada porque (C,C) no es más general que (B,A)

Posibilidades del sistema liberal

Soporte para constructoras existenciales

data key where mkKey :: A -> (A -> nat) -> key

getKey :: key -> natgetKey (mkKey X F) = F X

getKey (mkKey X F) :: natF :: A -> nat

X :: A

F X :: CF :: B -> C

X :: B

Bien tipada porque (C, B -> C, B) es más general que (nat, A -> nat, A)

Posibilidades del sistema liberal

Soporte para funciones indexadas por tipo (funciones con un comportamiento diferente para cada tipo)

eq :: A -> A -> booleq true true = true eq zero zero = trueeq true false = false eq zero (succ Y) = falseeq false true = false eq (succ X) zero = falseeq false false = true eq (succ X) (succ Y) = eq X Y

eq (X1,Y1) (X2,Y2) = (eq X1 X2) /\ (eq Y1 Y2)eq (snd X) (snd Y) = eq X Y

De esta manera se puede definir unaigualdad estructural mediante reglas, evitando

los problemas de descomposición opaca

Posibilidades del sistema liberal

Soporte para la funciones genéricas(funciones que sirven para todos los tipos con la misma definición)

data univ = c nat [univ]

usize :: univ -> natusize (c N L) = succ (sum (map usize L))

toU :: A -> univtoU true = c zero [] toU false = c (succ zero) []toU zero = c (succ2 zero) [] toU (succ X) = c (succ3 zero) [toU X]toU [] = c (succ4 zero) [] toU (X:Xs) = c (succ5 zero) [toU X, toU Xs]

size :: A -> natsize = usize . toU

Consideraciones

Se necesita declarar los tipos de las funciones para comprobar que un programa está bien tipado.

Se pierde la parametricidad en el sentido de Reynolds, ya que las reglas pueden inspeccionar argumentos polimórficos(Sin embargo la parametricidad no es aplicable PLF por más motivos: indeterminismo, variables extra o estrechamiento)

Se consideran como bien tipadas expresiones para las que no tenemos ninguna regla aplicable. Ejemplos: eq [ ] [ ], size [ ]... (no tan diferente de head [ ]).

1.Sistema de tipos con manejo seguro de patrones de orden superior

2.Sistema de tipos liberal

3.Aplicación del sistema de tipos liberal a la traducción de clases de tipos en PLF

4.Sistema de tipos con soporte para variables libres/extra y estrechamiento

5.Conclusiones

Motivación de la nueva traducción

Las clases de tipos proporcionan una manera modular y limpia de escribir funciones sobrecargadas

Tradicionalmente se implementan mediante una traducción que introduce diccionarios

Sin embargo, en PLF los diccionarios no interaccionan adecuadamente con el indeterminismo y la semántica de call-time choice, produciendo respuestas perdidas

Utilizando el sistema de tipos liberal, es posible una implementación alternativa de las clases de tipos en PLF que soluciona dicho problema a la vez que genera programas más rápido y compactos

Ejemplo problemático

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2 = [arb, arb]

Cada declaración de clasegenera una declaración de datos definiendo el

diccionario, además de funciones proyectoras

Ejemplo problemático

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2 = [arb, arb]

data dictArb A = dictArb A

arb :: dictArb A -> Aarb (dictArb F) = F

Ejemplo problemático

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2 = [arb, arb]

data dictArb A = dictArb A

arb :: dictArb A -> Aarb (dictArb F) = F

arbbool

:: bool

arbbool

= true

arbbool

= false

dictArbBool :: dictArb bool dictArbBool = dictArb arb

bool

Cada declaración deinstancia genera la definiciónde un diccionario concreto

Ejemplo problemático

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2 = [arb, arb]

data dictArb A = dictArb A

arb :: dictArb A -> Aarb (dictArb F) = F

arbbool

:: bool

arbbool

= true

arbbool

= false

dictArbBool :: dictArb bool dictArbBool = dictArb arb

bool

arbL2 :: dictArb A -> [A]arbL2 DA = [arb DA, arb DA]

Las funcionessobrecargadas son extendidas

para aceptar diccionarioscomo argumentos

Ejemplo problemático

data dictArb A = dictArb A

arb :: dictArb A -> Aarb (dictArb F) = F

arbbool

:: bool

arbbool

= true

arbbool

= false

dictArbBool :: dictArb bool dictArbBool = dictArb arb

bool

arbL2 :: dictArb A -> [A]arbL2 DA = [arb DA, arb DA]

Se pierden respuestas esperadas:

> arbL2::[bool]

De manera similar se genera el valor [false,false]

Sin embargo, los valores [true,false] y [false,true]

no se pueden alcanzar

Traducción alternativa: intuición

Pasar testigos de tipos (patrones que representan los distintos tipos) en lugar de diccionarios.(Enfoque propuesto en [Thatté,94])

Las funciones sobrecargadas son traducidas a funciones indexadas por tipo.

Estas utilizan el testigo pasado como argumento para decidir el comportamiento esperado.

Cada regla de una instancia genera una regla de la función indexada por tipo.

El programa traducido está bien tipado en el sistema liberal.

Testigos de tipos

Una manera de representar tipos como valores

Extender cada tipo de datos con una nueva constructora

Ejemplos: data nat = z | s nat | #nat data bool = true | false | #bool data [A] = nil | cons A (list A) | #list A

Los testigos de tipo tienen el mismo tipo que representan

#list #bool :: [bool]

#list (#list #nat) :: [[nat]]

Decoraciones

La traducción utiliza las decoraciones de tipos en los símbolos de función

Estas decoraciones son introducidas por una fase de comprobación de tipos previa utilizando el sistema de tipos usual de clase de tipos

g X = eq X [true]

g::[bool]->bool X = eq::<eq [bool]> => [bool]->[bool]->bool X [true]

Traducción: clases

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2::<arb A> => [A] = [arb::<arb A> => A, arb::<arb A> => A]

Cada función miembro declarada en una clase de tiposgenera una función indexada por tipo que

acepta un testigo de tipo

arb :: A -> A

Traducción: instancias

Cada regla de una función miembro generauna regla de la función indexada por tipoque acepta el testigo de tipo adecuado

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2::<arb A> => [A] = [arb::<arb A> => A, arb::<arb A> => A]

arb :: A -> A

arb #bool = truearb #bool = false

Traducción: funciones

class arb A where arb :: A instance arb bool where arb = true arb = false arbL2 :: arb A => [A]arbL2::<arb A> => [A] = [arb::<arb A> => A, arb::<arb A> => A]

Se pasan los testigos de tipos adecuados a lasfunciones sobrecargadas

arb :: A -> A

arb #bool = truearb #bool = false

arbL2 :: A -> [A]arbL2 X

A =

[arb XA, arb X

A]

Ventajas de la nueva traducción

arb :: A -> A

arb #bool = truearb #bool = false

arbL2 :: A -> [A]arbL2 X

A =

[arb XA, arb X

A]

Se recuperan las respuestas perdidas:

> arbL2::<eq bool> => [bool]

De manera similar se genera el valor [false,true]

A diferencia de los diccionarios (que contienenfunciones), la compartición de testigos de tipos

no es problemática porque son valores.

Ventajas de la nueva traducción

Programa Ganancia

eqlist 1.6

fib 2.3

galeprimes 1.5

memberord 2.3

mergesort 1

permutsort 1.7

quicksort 1

Mejora en el el tiempo de ejecución de los programas traducidos con respecto a los programas generados por la traducción clásica de clases de tipos.

Tests: fragmentos de programas reales que usan las clases clases de tipos eq, ord y num.

Ganancia media obtenida en el sistema Toy evaluando 100 expresiones aleatorias.

1.Sistema de tipos con manejo seguro de patrones de orden superior

2.Sistema de tipos liberal

3.Aplicación del sistema de tipos liberal a la traducción de clases de tipos en PLF

4.Sistema de tipos con soporte para variables libres/extra y estrechamiento

5.Conclusiones

Motivación

Los pasos de estrechamiento no preservan los tipos.

La sustitución unifica la expresión and true Y y el lado izquierdo de la regla and true X = X (aunque no es un unificador más general).

Sin embargo, el paso no preserva tipos

and true Y :: bool

zero :: nat

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

Motivación

Los pasos de estrechamiento no preservan los tipos.

La sustitución unifica la expresión and true Y y el lado izquierdo de la regla and true X = X (aunque no es un unificador más general).

Sin embargo, el paso no preserva tipos

and true Y :: bool

zero :: nat

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

¿El problema es queno son unificadores

más generales?

Motivación

Los pasos de estrechamiento utilizando unificadores más generales tampoco preservan los tipos.

La sustitución es un unificador más general de la expresión f (snd U) y el lado izquierdo de la regla de f.

Sin embargo, el paso no preserva tipos

(f (snd U),not U)::(bool,bool)

(true, not zero) está mal tipado

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

Motivación

Los pasos de estrechamiento utilizando unificadores más generales tampoco preservan los tipos.

La sustitución es un unificador más general de la expresión f (snd U) y el lado izquierdo de la regla de f.

Sin embargo, el paso no preserva tipos

(f (snd U),not U)::(bool,bool)

(true, not zero) está mal tipado

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

¿El problema son lospatrones de orden

superior?

Motivación

Las variables de orden superior también generan problemas para garantizar la preservación de tipos.

La sustitución es un unificador más general de la expresión F zero y el lado izquierdo de la regla de and false X = false.

Sin embargo, el paso no preserva tipos

succ (F zero) :: nat

succ false está mal tipado

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

Motivación

Es necesario estudiar bajo qué condiciones los pasos de estrechamiento generales

preservan los tipos

Clave de la pérdida de preservación de tipos

En todos los ejemplos las sustituciones utilizadas son sustituciones de estrechamiento válidas.

Sin embargo, son sustituciones mal tipadas. Esto es, sustituyen variables por patrones de otro tipo:

Las variables booleanas X e Y son sustituidas por zero.

La variable booleana U es reemplazada por zero.

La variable de orden superior F de tipo nat->nat es sustituida por and false, de tipo bool->bool. Además la variable booleana X es sustituida por zero.

Condición general

Si los pasos de estrechamiento usansustituciones bien tipadas, la

preservación de tipos está garantizada

Estrechamiento bien tipado

Sistema de tipos similar a Damas-Milner pero extendido para soportar variables extra en las reglas (λ-abstracciones)

La regla está bien tipada si el tipo de laλ-abstracción es una variante del tipo de f

Un programa está bien tipado – – si todas sus reglaslo están

Añadimos también suposiciones sobre laslas variables extra que solo aparecen en el

cuerpo de la λ-abstracción

Un paso de let-estrechamiento [López-Fraguas et al.,2008] es un paso de estrechamiento bien tipado ( ) si la sustitución θ es una sustitución bien tipada

Aspectos técnicos: como los pasos de estrechamiento pueden introducirnuevas variables, la noción de sustitución bien tipada y preservación de tiposdeben considerar suposiciones adecuadas para esas nuevas variables. Esas suposiciones están asociadas al paso de estrechamiento realizado.

Estrechamiento bien tipado

Problema operacional

Comprobar que las sustituciones están bien tipadas requiere comprobaciones en tiempo de ejecución en cada paso de estrechamiento.

¿Es posible encontrar una relación de estrechamiento más pequeña que evite dichas comprobaciones?

Sí, imponiendo restricciones sobre el programa y los pasos de estrechamiento

Estrechamiento reducido

Las sustituciones deben ser unificadores más generales Así solucionamos el problema en

Evitar los pasos que ligan variables de orden superior (comportamiento similar a la residuación)

Así solucionamos el problema en

Evitar patrones opacos en los lados izquierdos de las reglas Así solucionamos el problema en

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

Estrechamiento reducido

Las sustituciones deben ser unificadores más generales Así solucionamos el problema en

Evitar los pasos que ligan variables de orden superior (comportamiento similar a la residuación)

Así solucionamos el problema en

Evitar patrones opacos en los lados izquierdos de las reglas Así solucionamos el problema en

and :: bool -> bool -> bool f :: (A -> A) -> booland true X = X f (snd zero) = trueand false X = false

Patrón opaco

Estrechamiento reducido

Un paso de let-estrechamiento es un paso de estrechamiento reducido ( ) si:

No liga variables de orden superior

Utiliza un unificador más general

Los patrones en los lados izquierdos de las reglas son transparentes

Los pasos de estrechamiento reducido no necesitan comprobaciones en tiempo de ejecución

Los pasos de estrechamiento reducidoutilizando programas bien tipados

preservan los tipos

Estrechamiento necesario

Utilizando la preservación de tipos del estrechamiento reducido, es posible demostrar la preservación de tipos en un lenguaje Curry simplificado que utilice estrechamiento necesario [Antoy et al.,2000]

Lenguaje Curry simplificado: Patrones de primer orden → patrones transparentes

Residuación no liga → variables de orden superior

Enfoque transformacional: los pasos de estrechamiento necesarios son simulados por pasos de estrechamiento reducido (que preserva tipos) sobre un programa transformado.

Estrechamiento necesario

Idea de la demostración:

Ambas transformaciones generan programas bien tipados.

Las reducciones de estrechamiento necesario sobre el programa original P son simuladas con reducciones de estrechamiento reducido sobre el programa transformado en formato uniforme P''. Por lo tanto preservan los tipos.

OISP P' Formatouniforme

P''

[Antoy,2001] [Zartmann,1997]

1.Sistema de tipos con manejo seguro de patrones de orden superior

2.Sistema de tipos liberal

3.Aplicación del sistema de tipos liberal a la traducción de clases de tipos en PLF

4.Sistema de tipos con soporte para variables libres/extra y estrechamiento

5.Conclusiones

Conclusiones

1. Manejo adecuado de los patrones de orden superior

Publicaciones: LNCS con artículos revisados y seleccionados de WFLP'09, Information & Computation (2013)

Definición de las variables opacas en un patrón (aquellas cuyo tipo no está completamente determinado por el tipo del patrón)

Impedir la aparición de variable opacas en los cuerpos de let-expresiones y λ-abstracciones: variables críticas

Conclusiones

2. Desarrollo de un sistema de tipos relajado para PLF que garantiza la preservación de tipos

Publicaciones: APLAS '10, Mathematical Structures in Computer Science (2013)

El lado derecho de las reglas no debe restringir el tipo más que el lado izquierdo

Aplicaciones: soporta funciones indexadas por tipo, programación genérica, constructoras existenciales.

Ejemplo destacado: Traducción alternativa de clases de tipos (PEPM '11)

Es lo más relajado posible garantizando la preservación de tipos.

Conclusiones

3. Manejo adecuado del problema de la descomposición opaca

Al permitir funciones indexadas por tipo, la igualdad estructural se puede definir por reglas y no ser una primitiva ad-hoc

Las reglas que conducen a la descomposición opaca son consideradas mal tipadas, ya que no preservan el tipo

Conclusiones

4. Manejo adecuado de las variables libres y extras, garantizando la preservación de tipos con estrechamiento

Publicaciones: PEPM '12

Los pasos de estrechamiento con sustituciones bien tipadas preservan los tipos

El estrechamiento reducido preserva los tipos sin necesidad de comprobaciones en tiempo de ejecución

Aplicaciones: demostrar la preservación de tipos del estrechamiento necesario

Publicaciones Francisco J. López Fraguas, Enrique Martin-Martin, Juan Rodríguez-Hortalá

Safe Typing of Functional Logic Programs with Opaque Patterns and Local BindingsInformation and Computation, aparecerá en 2013

Francisco J. López Fraguas, Enrique Martin-Martin, Juan Rodríguez-HortaláA Liberal Type System for Functional Logic ProgramsMathematical Structures in Computer Science, aparecerá en 2013

Francisco J. López Fraguas, Enrique Martin-Martin, Juan Rodríguez-HortaláWell-typed Narrowing with Extra Variables in Functional-Logic ProgrammingACM SIGPLAN 2012 Workshop on Partial Evaluation and Program Manipulation (PEPM), 2012

Enrique Martin-MartinType Classes in Functional Logic ProgrammingACM SIGPLAN 2011 Workshop on Partial Evaluation and Program Manipulation (PEPM), 2011

Francisco J. López Fraguas, Enrique Martin-Martin, Juan Rodríguez-HortaláLiberal Typing for Functional Logic Programs 8th Asian Symposium on Programming Languages and Systems (APLAS), 2010

Francisco J. López Fraguas, Enrique Martin-Martin, Juan Rodríguez-HortaláNew Results on Type Systems for Functional Logic Programming18th International Workshop on Functional and (Constraint) Logic Programming –RevisedSelected Papers–, 2009

Sistemas

Rama de Toy 2.3.1 con patrones opacos seguroshttp://gpd.sip.ucm.es/Toy2SafeOpaquePatterns

Rama de Toy 2.3.1 con sistema de tipos liberalhttp://gpd.sip.ucm.es/Toy2Liberal

Interfaz web del sistema de tipos liberal (soporte de sintaxis GADT)http://gpd.sip.ucm.es/LiberalTyping

Trabajo futuro

Patrones opacos Aplicar un enfoque similar al de los tipos existenciales

[Läufer & Odersky, 1994] para tratar las variables opacas

No todas las variables críticas generan problemas. Relajar el sistema de tipos para permitir usos seguros de las variables críticas. Primeros avances realizados en (Information and Computation 2013)

Trabajo futuro

Sistema de tipos liberal Aunque en general no existen tipos principales, estudiar

situaciones donde algún tipo de inferencia es posible

Considerar la combinación del sistema de tipos liberal, clases de tipos y el sistema de tipos con manejo de variables opacas. Estudiar las propiedades del sistema resultante (preservación de tipos, tipos principales, etc.)

Trabajo futuro

Traducción alternativa de clases de tipos Implementar completamente la traducción en Toy para poder

comprobar la ganancia de velocidad con conjunto amplio de programas reales

Investigar si en la traducción encajan conocidas extensiones de las clases de tipo como clases multiparámetro o clases de constructoras

Trabajo futuro

Descomposición opaca Ampliar la expresividad del sistema de tipos para que igualdades

que provocan descomposición opaca sean consideradas mal tipadas. Requeriría ampliar la información de tipos para expresar los tipos de sus sub-expresiones (enviado a PPDP '12)

Trabajo futuro

Variables libres y estrechamiento Afinar el sistema de tipos para que el estrechamiento reducido

preserve tipos aún considerando patrones opacos en la reglas. Para ello parece ser conveniente recuperar la parametricidad del sistema de tipos, posiblemente utilizando un enfoque similar a los tipos existenciales.

¡Gracias!