230 likes | 346 Views
Optimización automática de programas. Tema 2: Funciones, tipos y expresiones 2.1. Funciones 2.2. Tipos 2.3. Tipos de datos recursivos. 2.1. Funciones. t. Una función puede ser total f: A B parcial f: A B Para ello, debe cumplir aA,bB.(a,b)f (a,b’) f b=b’
E N D
Optimización automática de programas Tema 2: Funciones, tipos y expresiones 2.1. Funciones 2.2. Tipos 2.3. Tipos de datos recursivos Germán Vidal
2.1. Funciones t • Una función puede ser • total f: A B • parcial f: A B • Para ello, debe cumplir • aA,bB.(a,b)f (a,b’) f b=b’ • aA, bB.(a,b)f [(a,b)f f(a) = f a = b] La primera condición es necesaria para toda función (total o parcial) y la segunda sólo para las funciones totales Germán Vidal
Ejercicio • ¿Cómo se puede convertir una función parcial en total? Germán Vidal
Conceptos básicos • Igualdad de funciones: • dos funciones f,g: A B son iguales (f=g) si aA. f(a) = g(a) • Composición de funciones: • la composición de dos funciones f: A B y g: B C es una nueva función g o f: A C tal que aA. (g o f)(a) = g(f(a)) Germán Vidal
Funciones finitas: • dados los elementos a1,…,anA y b1,…,bnB la notación [a1 b1,…,an bn] representa la función (parcial) g: A B tal que g(x) = bi si x=ai para algún i g(x) = si xai para todo i • Updating: • dada una función f:A B, la notación f[a1 b1,…,an bn] denota la función g:A B tal que g(x) = bi si x=ai para algún i g(x) = f(x) si xai para todo i se denomina la “actualización” de f mediante [ai bi] Germán Vidal
Funciones vs algoritmos • las funciones matemáticas no siempre definen un algoritmo (e.g., f(n) = el n-ésimo dígito decimal de ) • los algoritmos no tienen porque cumplir la primera condición de toda función (devolver un valor único) (e.g., debido a la E/S o a las variables globales) • Ejercicio 2.6: ¿Qué conjunto tiene más elementos? Fun = { f | f es una función parcial N N } Prog = { p | p es un programa Pascal que implementa una función N N } Germán Vidal
2.2. Tipos • Tipo = conjunto de valores • Expresiones de tipo: • Nombres de tipos estándar N (naturales), Z (enteros), B (booleanos), ID (identificadores) • Tipos producto: si A1,A2,…,An son tipos, entonces A1 A2 … An es un tipo válido • Tipos funcionales: si A y B son tipos, entonces A B y A B son tipos válidos • Una función f: A Bes de orden superior si A o B son de tipo funcional (y de primer orden en otro caso) Germán Vidal
Ejemplos • Función tipo square(x) = x2 square: N N h(m,n) = m+n h: N N N k(m,n) = (m+n, m-n) k: Z Z Z Z sum(f,x) = f(0)+…+f(x) sum: (NN) N N add(n) = p donde add: N (N N) p(x) = x+n twice(f)(x) = f(f(x)) twice:(NN) (NN) ... Germán Vidal
Ejercicio 2.2 • Escribid funciones que ilustren la diferencia entre los tipos A (B C) y (A B) C Germán Vidal
Notación currificada • Podemos escribir la función suma así: suma: N N N suma(x,y) = x+y pero también así: add: N (N N) add(x) = p, donde p(y) = x+y • Decimos que add es una versión “currificada” de suma (viene de Haskell B. Curry) Germán Vidal
Ejercicio 2.3 • Los tipos A (B C) y A B C son parecidos pero no idénticos… • Define una función uncurry tal que, si la función f es de tipo A (B C),entonces (uncurry f) será de tipo A B C Germán Vidal
Inferencia de tipos • Notación: • x:t “x es una variable cuyos valores son de tipo t” • e:t “e es una expresión bien tipada y su valor es de tipo t” • Cuando una expresión contiene variables, necesitamos conocer el “entorno de tipo” τ = [x1 t1,…,xn tn] • En general, usaremos sentencias de la forma τ├ e:t para indicar que “en el entorno τ, e está bien tipada y tiene tipo t" Germán Vidal
Reglas de inferencia de tipos (ejemplos) • τ[x t]├ x:t • τ├ e:B τ├ not e:B • τ├ e1:Z τ├ e2:Z τ├ e1 + e2:Z • τ├ e1:t1τ├ e2:t2 τ├ (e1,e2):t1 t2 • τ├ f:t t’ τ├ e:t τ├ f(e):t’ Germán Vidal
Ejemplos • Verificar que τ├ (m+n,m-n): Z Z con el entorno τ = [m Z, n Z] • Verificar que τ├ f(f(x)): N con el entorno τ = [f (N N), x N] Germán Vidal
Ejercicio 2.4 • Verificar que, si los argumentos m y n tienen ambos tipo Z, entonces la expresión k(m,n) tiene tipo Z Z (nota: el tipo de la función k lo podéis encontrar en la transparencia 8) Germán Vidal
Tipos suma (constructores de datos) • Permiten combinar elementos de diferentes tipos mediante el uso de “etiquetas” (o símbolos constructores) • Ejemplo: ZB = Int Z | Bool B (e.g., Int 42, Bool true, Int -7, Bool false) • Definición general: tipo = C1 t11 x … x t1k1 | … | Cn tn1 x … x tnkn i.e., el tipo contiene los valores Ui=1,…,n {Ci(v1,…,vki) | vj:tij, j = 1,…,ki} Germán Vidal
Tipos suma: ejemplos data ZB = I int | B bool f :: ZB -> ZB f (I n) = I (1-n) f (B b) = B (not b) // f(I(n)) = I(1-n) // f(B(b)) = B(not(b)) data list = Nil | Cons int list length :: list -> int length Nil = 0 length (Cons x xs) = 1 + (length xs) Germán Vidal
Usamos notación Haskell/ML • En los lenguajes funcionales Haskell o ML, las funciones se definen mediante “patrones” en las partes izquierdas: length Nil = 0 length (Cons x xs) = 1 + (length xs) • En otros lenguajes (e.g., Lisp o Scheme) se suelen utilizar expresiones “case” (u otro tipo de selectores): length y = case y of Nil -> 0 Cons x xs -> 1 + (length xs) Germán Vidal
2.3. Tipos de datos recursivos • Suele ser un tipo suma con recursión en la definición, e.g., data list = Nil | Cons int list • El tipo lista es uno de los tipos de datos recursivos más usados! • Notación • A* o [A] denota una lista de elementos de tipo A • Cons(a1,Cons(a2,Nil)) = [a1,a2] • Nil = [], [a1,a2] = (a1:(a2:[])) • [x|xs] = (x:xs) • operadores típicos: head / tail Germán Vidal
Árboles sintácticos • A menudo, se emplean para hacer más clara la estructura de una expresión • Ejemplo: dado el tipo de datos data exp = I int | Sum exp exp | Mul exp exp la estructura de la expresión Sum(I(5),Mul(I(6),I(7))) (i.e., 5+(6*7)) se visualiza mejor así: Germán Vidal
Árboles sintácticos (cont.) Sum I Mul 5 I I 6 7 Germán Vidal
Ejercicio 2.5 • Define un tipo de datos recursivo Bintree para representar árboles binarios cuyas hojas sean enteros • Define también una función add de tipo Bintree int tal que (add tree) nos devuelva la suma de todas las hojas del árbol tree Germán Vidal
Ejercicio • Declara su tipo de datos e implementa las siguientes funciones • last: toma una lista y devuelve el último elemento • reverse: toma una lista y devuelve su inversa • concat: concatena dos listas • map: toma una función (unaria) y una lista y devuelve la lista resultante de aplicar la función a cada elemento de la lista Germán Vidal