1 Derivando un algoritmo de inferencia de tipos El sistema de inferencia polimórfico no es syntax-directed. Las reglas (inst) y (gen) pueden ser aplicadas.

Slides:



Advertisements
Presentaciones similares
Relaciones de recurrencia
Advertisements

Seminario: Interpretaciones y Modelos Conjuntistas
Diseño y análisis de algoritmos
Diseño y análisis de algoritmos
Compiladores e intérpretes Análisis Sintáctico III
Curso de java básico (scjp)
TECNICATURA UNIVERSITARIA EN INFORMATICA
FACTORIZACIÓN LU Bachilleres:
funciones Por: Carlos Alberto García Acosta
Clases Extendidas La clase extendida hereda los campos y métodos de la clase de la cual extiende. La clase original se conoce como superclase y la clase.
MATRIZ DE CHEQUEO DE PARIDAD
METODO DE LOS COEFICIENTES INDETERMINADOS
Interpretando objetos
1 Parsing Un parser podría ser definido como un programa que analiza una porción de texto para determinar su estructura lógica: la fase de parsing en un.
Chequeo e inferencia de tipos
Variaciones sobre un evaluador Objetivo: Mostrar cómo un estilo de programación monádica puede capturar similitudes entre distintas variaciones de un elemental.
1 Agregando primitivas 2 Introducción Ahora presentaremos cómo agregar operaciones primitivas a la máquina G. Entenderemos como operaciones primitivas.
Programación monádica
Combinadores SK.
Tipo de Dato Abstracto Tipos de datos:
Análisis Matemático III
Informática II Prof. Dr. Gustavo Patiño MJ
KRIGING.
UNIVERSIDAD LATINA (UNILA) IV. IMPLANTACION DE ALGORITMOS.
Aplicación del paradigma orientado a objetos
CÁLCULO DIFERENCIAL.
RESOLUCION DE PROBLEMAS, MEDIANTE SISTEMAS DE ECUACIONES
ANALISIS SINTACTICO DESCENDENTE
Ecuaciones diferenciales de 1er orden :
2.1 Recursividad El hecho de que una función pueda llamarse a sí misma.
Tema 7: Polimorfismo Antonio J. Sierra. Índice Introducción. Sobrecarga de métodos. Objetos como parámetros. Paso de argumentos. Devolución de objetos.
Funciones Como calculadora, Notación f(x), dominio restringido y recorrido o rango.
Función Lineal.
ANALISIS SINTACTICO El análisis gramatical es la tarea de determinar la sintaxis, o estructura, de un programa. Por esta razón también se le conoce como.
Teoría de lenguajes y compiladores
Tema 6: Clases Antonio J. Sierra.
La derivada de la función inversa y de funciones especiales
2- SIMPLEX.
Tema 2: LA ELECCIÓN RACIONAL DEL COSUMIDOR
Semana 5 Subprogramas..
Método de Gauss-Seidel
Programación en Matlab
La Derivada. Ya vimos: los conceptos, métodos ó instrumentos necesarios para establecer el “comportamiento” de una función.  en un entorno de x o [ 
TIPOS DE MODELOS DE REGRESIÓN Y SUPUESTOS PARA EL MODELO A
TEMA 4 TRANSFORMADA DE LAPLACE
Estructura de Datos y Algoritmos
Extensiones sintácticas Revisaremos formas especiales que son sintácticamente equivalentes a patrones que son expresables en términos de formas básicas.
Tipos de Datos (Data Types)
Material de apoyo Unidad 4 Estructura de datos
Semantica.
EXPRESIONES Y SENTENCIAS
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.
TPPSFAsistentes para programadores Asistentes de Pruebas para Programadores Cálculo de Construcciones.
1 Samba: Un lenguaje funcional perezoso Presentación del lenguaje: qué es un programa Samba definiciones locales abstracciones lambda Tipos inductivos:
1 Compilación, pereza y expresiones let(rec) 2 Compilando un programa Describiremos un compilador para la máquina minimal usando un conjunto de esquemas.
Como veremos una función es una ley de asociación entre
Procesamiento Digital de Imágenes
Conceptos Avanzados de Programación
Sistemas Basados en Reglas
Tema 2: LA ELECCIÓN RACIONAL DEL COSUMIDOR Introducción. La restricción presupuestaria. Las preferencias del consumidor. El equilibrio del consumidor.
@ Angel Prieto BenitoApuntes de Matemáticas 3º ESO1 SISTEMAS DE ECUACIONES Tema 6 * 3º ESO.
Método Simplex Es un procedimiento sistemático y eficiente para encontrar y probar soluciones situadas en los puntos extremos de la región de soluciones.
6. Sistemas de ecuaciones diferenciales lineales
Regla de la cadena en varias variables
Análisis cinemático: VELOCIDAD
Hernández Camacho Víctor Jesus Islas Sánchez Karla Vanessa
Ing. Haydeli del Rosario Roa Lopez
Solución a Ecuaciones de Recurrencia Dr. Rogelio Dávila Pérez División de Posgrado Universidad Autónoma de Guadalajara
Ecuaciones Diferenciales Ordinarias de Primer Orden. Tema # 1.
Tipos genéricos Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Unidad Didáctica 3.
Transcripción de la presentación:

1 Derivando un algoritmo de inferencia de tipos El sistema de inferencia polimórfico no es syntax-directed. Las reglas (inst) y (gen) pueden ser aplicadas en cualquier paso de la derivación. Sin embargo, es posible restringir el uso de: (inst) inmediatamente después de las reglas (var) y (con) (gen) inmediatamente antes de (let) para obtener los esquemas más generales para las variables definidas. A continuación presentaremos un sistema modificado que fuerza las restricciones arriba discutidas, y que no incluye las reglas (inst) y (gen). Def. Esquema más general Gen( ,T) =      n   T donde {      n   = FV(T) - FV(  )

2 (var)  |- x : T si x : S está en  y S  T (con)  |- c : T si c : S está en  y S  T   |- f : T -> T’  |- e : T  (ap)   |- f e : T’  |- a : T  |- b : T’  (prod)   |- (a,b) : T x T’  |- b : Bool  |- e : T  |- d : T  (if)   |- if b then e else d : T  |- e’ : T’  x:S  |- e : T (let)  donde S = Gen( ,T’)  |- let x = e’ in e : T   x:T’  |- e : T  (abs)   |- \ x -> e : T’ -> T

3 Representación de expresiones de tipos Para construír el algoritmo necesitaremos representar expresiones de tipos como objetos de un tipo Haskell: type TVname = [Int] data Texp = Tvar TVname | Tcons String [Texp] deriving(Eq,Read,Show) -- some types arrow t1 t2 = Tcons "arrow" [t1,t2] int = Tcons "int" [] bool = Tcons ”bool" [] cross t1 t2 = Tcons "cross" [t1,t2] list t = Tcons "list" [t]

4 La mónada [] instance Monad [] where return a = [a] l >= f = concat (map f l) bar :: Eq a => [a]->[a]->[a] bar l b = [ x  l  x notElem b ] -- the type variables in a type tvars_in (Tvar x) = return x tvars_in (Tcons name args) = args >= tvars_in

5 Resolviendo ecuaciones Consideremos el chequeo de una expresión (Ap e 1 e 2 ), donde hemos derivado el tipo t 1 para e 1 y el tipo t 2 para e 2. Entonces tendríamos que resolver la siguiente ecuación: t 1 = t 2 -> (Tvar n) donde n es un nombre de variable de tipo que no ha sido previamente usado. Como ya hemos visto en el chequeo de una expresión se generan restricciones, las que pueden ser entendidas como ecuaciones entre (esquemas) de tipos. Soluciones a estas ecuaciones pueden ser entendidas (e implementadas) como sustituciones de variables (de tipos) por expresiones de tipos. Entonces: -- substitutions type Subst = TVname -> Texp

6 Sustituciones Dada una sustitución phi y una expresión de tipo te, definimos a (sub_type phi te) como la expresión obtenida a partir de aplicar la sustitución phi a todas las variables de tipo en te: sub_type :: Subst -> Texp -> Texp sub_type phi (Tvar x) = phi x sub_type phi (Tcons name args) = Tcons name (map (sub_type phi) args) Dos sustituciones pueden ser compuestas para definir otra sustitución: subst_comp :: Subst -> Subst -> Subst subst_comp phi psi x = sub_type phi (psi x) Propiedad: sub_type (subst_comp phi psi) = (sub_type phi). (sub_type psi)

7 Sustituciones (2) La sustitución identidad id_subst :: Subst id_subst x = Tvar x Una sustitución delta es aquella que sólo afecta a una variable delta :: TVname -> Texp -> Subst delta x t y = if y == x then t else Tvar y En general una sustitución puede asociarle a una variable un valor que a su vez tambien contiene variables. Si esas variables a su vez forman parte del dominio de la sustitución, entonces la misma no esta “completamente resuelta”. Un proceso iterativo podría ser necesario (problema de terminación si hay circularidad).

8 Sustituciones (3) En general, estaremos interesados en obtener sustituciones normalizadas. La siguiente definición captura esta noción Def. Una sustitución phi es idempotente si se cumple que (sub_type phi). (sub_type phi) = sub_type phi Def. Una expresión de tipo t es un punto fijo de una sustitución phi si sub_type phi t = t En particular, si (Tvar x) es un punto fijo de phi, diremos que x no es afectada por phi. Notar que si phi es idempotente, y phi afecta a tvn, entonces sub_type phi (Var tvn) es un punto fijo de phi

9 Unificación Ahora mostraremos cómo construír una sustitución que resuelva un conjunto dado de ecuaciones de tipos, usando unificación. Un sistema de ecuaciones puede ser representado como una lista de pares de expresiones de tipos. Para resolver las ecuaciones, debemos hallar una sustitución phi que unifique las partes izquierdas y derechas de todas las ecuaciones en el sistema, donde decimos que phi unifica al par (t 1, t 2 ) si se cumple sub_type phi t 1 = sub_type phi t 2 Def. Una sustitución phi es no menos general que una sustitución psi si existe rho tal que psi = rho `subst_comp` phi

10 Unificación (2) El problema de unificación es el de hallar un unificador maximalmente general e idempotente de un conjunto de pares de expresiones [Robinson 65]. Será conveniente para la construcción del algoritmo considerar el problema de extender una sustitución que resuelve un conjunto de ecuaciones a una que resuelve una extension de ese conjunto. Formularemos el problema de la siguiente forma: Dado un par (t 1,t 2 ) de expresiones de tipos, y una sustitución idempotente phi, nuestro algoritmo debería retornar un error si no existe una extensión de phi que unifica (t 1,t 2 ), y si no retornar (Ok psi) donde psi es un unificador idempotente de (t 1,t 2 ) que extiende a phi.

11 Unificación (3) La ecuación más simple a resolver es una de la forma Tvar tvn = t Para manejar estos casos haremos uso de la siguiente función extend :: Subst -> TVname -> Texp -> E Subst extend phi x t = if t == Tvar x then return phi else if elem x (tvars_in t) then errorE “occur check” else return (subst_comp (delta x t) phi) Una expresión (extend phi tvn t) será evaluada sólo cuando: i) phi es una sustitución idempotente ii) t es un punto fijo de phi iii) tvn no es afectada por phi (tvn no tiene un valor bajo phi)

12 Unificación (4) unify :: Subst -> (Texp,Texp) -> E Subst unify phi (Tvar x,t) = if phix == Tvar x then extend phi x t else unify phi (phix,phit) where phix = phi x phit = sub_type phi t unify phi (Tcons n args,Tvar x) = unify phi (Tvar x,Tcons n args) unify phi (Tcons n1 args1,Tcons n2 args2) = if n1 == n2 then unifyl (return phi) (zip args1 args2) else errorE “Different type constructors” unifyl :: E Subst -> [(Texp,Texp)] -> E Subst unifyl = foldr (\eq -> \ms -> ms >= (\s -> unify s eq))

13 Esquemas de tipos y genericidad Representaremos esquemas de tipos como objetos del siguiente tipo Haskell data TypeScheme = Scheme [TVname] Texp Una variable de tipo que ocurre en un esquema (Scheme scvs t) es genérica si su nombre es un elemento de la lista scvs, en caso contrario será una variable no-genérica nonGenericOfScheme :: TypeScheme -> [TVname] nonGenericOfScheme (Scheme l t) = bar (tvars_in t) l Aplicando una sustitución a un esquema de tipo sin afectar variables genéricas sub_scheme :: Subst -> TypeScheme -> TypeScheme sub_scheme phi (Scheme l t) = Scheme l (sub_type (exclude phi l) t) where exclude phi l x = if (elem x l) then (Tvar x) else (phi x)

14 Listas de asociación Cómo reflejar el hecho de que a cada variable libre en una expresión le asociaremos un esquema de tipo? Requerimientos sobre le estructura de datos: i) debe proveer un mapeo de variables libres a esquemas ii) tendríamos que ser capaces de determinar cuál es el recorrido de ese mapping Consideremos el chequeo de (let x = e in e´) 1) derivamos un tipo T para e en un contexto x 1 : S 1... xn : S n, lo que equivale a construir una sustitución phi para las ecuaciones implicadas por la estructura de e tal que e : T en el contexto x 1 : S 1 ´... xn : S n ´, donde S i ´ es la imagen de S i bajo phi. 2) Formamos el esquema S que asociaremos a x en el contexto, tal que las variables genéricas de S son aquellas de T excepto las no- genéricas que ocurran en S 1 ´... S n ´.

15 Listas de asociación (2) Entonces cualquiera sea la estructura elegida para representar contextos nos deberá permitir acceso al conjunto de variables no- genéricas de su recorrido. type AssocList a b = [(a,b)] dom :: AssocList a b -> [a] val :: Eq a => AssocList a b -> a -> b install :: AssocList a b -> a -> b -> AssocList a b -- the range of an association list is the list of -- values (as obtained with val) rng :: Eq a => AssocList a b -> [b] rng al = map (val al) (dom al)

16 Contextos type Context = AssocList Vname TypeScheme nonGenericOfCtx :: Context -> [TVname] nonGenericOfCtx gamma = (rng gamma) >= nonGenericOfScheme sub_ctx :: Subst -> Context -> Context sub_ctx phi gamma = gamma >= (\(x,st) -> [(x,(sub_scheme phi st))]) Variables Frescas type NameSupply = TVname name_sequence :: NameSupply -> [TVname]

17 Inferencia de tipos Finalmente, ahora estamos en condiciones de definir el algoritmo de inferencia. Este será una función (tc gamma ns e), donde i) gamma es un contexto. Cuando el chequeador es invocado debe estar inicializado con los tipos de los identificadores predefinidos. ii) ns provee nombres frescos de variables de tipos iii) e es la expresión a ser chequeada El valor retornado será un objeto de la mónada E, el que en caso de éxito retornará un par (phi,t), donde i) phi es una sustitución definida sobre las variables no-genéricas de gamma ii) t es un tipo derivado para la expresión e, en el contexto (sub_ctx phi gamma). Será un punto fijo de phi.

18 Inferencia de tipos (2) Definiremos la función tc por inducción en la estructura de las expresiones, con una clausula diferente por cada una de ellas: tc :: Context -> NameSupply -> Exp -> E (Subst,Texp) tc gamma ns (Var x) = tcvar gamma ns x tc gamma ns (Ap e1 e2) = tcap gamma ns e1 e2 tc gamma ns (Lambda x e) = tclambda gamma ns x e tc gamma ns (Let decls e) = tclet gamma ns (map fst decls) (map snd decls) e tc gamma ns (LetRec decls e) = tcletrec gamma ns (map fst decls) (map snd decls) e

19 Funciones auxiliares add_decls :: Context -> NameSupply -> [Vname] -> [Texp] -> Context add_decls gamma ns xs ts = (zip xs schemes)++gamma where schemes = map (genbar nongeneric ns) ts nongeneric = nonGenericOfCtx gamma genbar u n t = Scheme (map snd al) t' where al = zip scvs (name_sequence n) scvs = bar (nub (tvars_in t)) u t' = sub_type (al2subst al) t tcl :: Context -> NameSupply -> [Vexp] -> E(Subst,[Texp]) tcl gamma ns [] = return(id_subst,[]) tcl gamma ns (e:es) = do (phi,t) <- tc gamma ns1 e (psi,ts) <- tcl (sub_ctx phi gamma) ns0 es return (subst_comp psi phi,(sub_type psit):ts))) where (ns0,ns1) = split ns

20 Chequeando variables Cuando chequeamos una variable x en un cierto contexto gamma, con nombres ns, miramos el esquema de tipos asociado a la variable en gamma. Retornamos una nueva instancia del esquema donde las variables genéricas han sido reemplazadas por variables frescas tcvar :: Context -> NameSupply -> Vname -> E(Subst,Texp) tcvar gamma ns x = return(id_subst,new_instance ns (val gamma x)) new_instance :: NameSupply -> TypeScheme -> Texp new_instance ns (Scheme scvs t) = sub_type phi t where phi = al2subst (zip scvs (name_sequence ns)) al2subst al x = if (elem x (dom al)) then Tvar (val al x) else Tvar x

21 Chequeando aplicaciones Cuando chequeamos una aplicación (Ap e 1 e 2 ), primero construímos una sutitución phi que resuelva las restricciones sobre e 1 y e 2. Supongamos que t 1 y t 2 fueron derivados respectivamente. Luego tratamos de construír una extensión de phi que satisfaga el requerimiento adicional de que t 1 = t 2 -> t’, donde t’ es una variable fresca. tcap :: Context -> NameSupply -> Exp -> Exp -> E(Subst,Texp) tcap gamma ns e1 e2 = do (phi,[t1,t2]) <- tcl gamma (deplete ns) [e1,e2]) let x = next_name ns psi <- unify phi (t1, arrow t2 (Tvar x)) return (psi,psi x)

22 Chequeando abstracciones Cuando chequeamos una abstracción (Lambda x e) asociamos x con un esquema de la forma (Scheme [] (Tvar tvn)), donde tvn es una variable fresca. Como este esquema no tiene variables genéricas las distintas ocurrencias de x en e serán asignadas el mismo valor de la variable de tipo. tclambda :: Context -> NameSupply -> Vname -> Vexp -> E (Subst,Texp) tclambda gamma ns x e = do (phi,t) <- tc gamma' ns' e return (phi,arrow (phi tvn) t)) where gamma' = new_bvar(x,tvn) : gamma ns' = deplete ns tvn = next_name ns new_bvar (a,b) = (a,Scheme [] (Tvar b))

23 Chequeando expresiones let Cuando chequeamos una expresión (Let [(x,e)] e’), primero chequeamos las partes derechas de las definiciones. Luego tenemos que actualizar el contexto para asociar los esquemas apropiados con los nombres de las definiciones. tclet :: TypeEnv -> NameSupply -> [Vname] -> [Exp] -> Eexp -> E (Subst,Texp) tclet gamma ns xs es e = do (phi,ts) <- tcl gamma ns1 es (psi, t) <- tc (add_decls (sub_ctx phi gamma) (fst (split ns0)) xs ts) (snd (split ns0)) e) return (subst_comp phi psi, t) where (ns0,ns1) = split ns

24 Chequeando expresiones letrec Para chequear expresiones de la forma (Letrec [(x,e)] e’) seguiremos los siguientes pasos: i) Asociaremos nuevos esquemas de tipos a los nombres de las definiciones, estos esquemas no incluirán variables genéricas. ii) Chequearemos las partes derechas de las definiciones. Si tenemos éxito, este paso generará una sustitución y una lista de tipos, los que pueden ser derivados para las expresiones si el contexto es restringido por la sustitución. iii) Unificaremos los tipos derivados para las partes derechas con los esquemas asociados a las variables, de acuerdo a las restricciones impuestas por la sustitución. Con esto respetamos el criterio de mismo tipo en parte derecha para todas las ocurrencias de los nombres. iv) Procedemos como lo hicimos con expresiones let.

25 Chequeando patterns y case Al chequear una expresión (case e of p 1 -> e 1... p n -> e n ) tenemos que asegurar lo siguiente: i) los patrones son lineales ii) la expresión e tiene un tipo T iii) todos los patrones tienen el mismo tipo T iv) todas las expresiones e i tienen un mismo tipo T´ v) el tipo de cada expresión e i es derivado en un contexto que considere el tipo del patron p i (componentes)  |- (p 1 : T) =>  .   |- (p n : T) =>  n  |- e : T    |- e 1 : T...  n  |- e n : T (case)   |- case e of p 1 -> e 1... p n -> e n : T´ donde

26 Chequeando patterns y case (2)   |- (x : T) =>  x:T]  |- (C : T)  |- (c : T) =>  ]   |- (p 1 : T 1 ) =>   .  |- (p n : T n ) =>  n  |- ((p 1,...,p n ) : T 1,...,T n ) =>      n   |- (p : T 1 ) =>   .  |- C : T 1 -> T  |- ( C p : T) =>  