Algoritmos y Estructuras de Datos I Algoritmos y Estructuras de Datos I Clases teóricas I Segundo cuatrimestre de 2014 Profesores Verónica Becher, Hernán Melgratti, Paula Zabala Clases prácticas Departamento de Computación - FCEyN - UBA Especificación - clase 1 I Mañana: Rodrigo Castaño, Esteban Pavese, Alexis Tcatch (JTPs) I Noche: Brian Curcio, Gabriela Di Piazza (JTPs) Sitio web de la materia: http://www.dc.uba.ar/people/materias/algo1 Introducción a la especificación de problemas Lógica proposicional 1 2 Algoritmos y Estructuras de Datos I Régimen de aprobación I parciales I I I 2 parciales 2 recuperatorios (al final de la cursada) [email protected] trabajos prácticos I I I [email protected] 2 entregas 2 recuperatorios (cada uno a continuación) grupos de 4 alumnos Exámen final I o en caso de tener dado el final de Álgebra, coloquio. Calificacion= promedio de la cursada y el nota del coloquio, cursada = p1 + p2 + t1 + t2 4 3 4 Bibliografı́a I A Method of Programming Edsger Dijkstra, W. H. Feijen Addison-Wesley Longman, 1988 I Structured Programming Edsger Dijkstra, C. A. R. Hoare, Ole-Johan Dahl Academic Press, 1972 ¿Qué es una computadora? I A Discipline of Programming Edsger Dijkstra Prentice Hall , 1976 I Mathematical Logic: A Course With Exercises, Part 1 René Cori, Daniel Lascar. Oxford University Press, 2000 I The Science of Programming David Gries Springer Verlag, 1981 I Reasoned programming K. Broda, S. Eisenbach, H. Khoshnevisan, S. Vickers, Prentice-Hall, 1994 5 6 ¿Qué es una computadora? ¿Qué es un algoritmo? Dispositivo para manipulación simbólica que ejecuta cualquier algoritmo. Matemáticamente, es una función recursiva parcial universal. 7 8 Definición de Algoritmo Pasos primitivos Problema: sumar dos números naturales I Algoritmo suma escolar: sumo las unidades del primero a las del segundo, después las decenas y ası́ (“llevándome uno de acarreo” cuando hace falta). I Algoritmo sucesor: voy sumando uno al primero y restando uno al segundo, hasta que llegue a cero. I Algoritmo moderno: escribo el primero en una calculadora, aprieto +, escribo el segundo, aprieto =. Un algoritmo es una sucesión de pasos primitivos que permiten resolver un problema. ¿Con qué pasos primitivos contamos? Ejemplo: Problema sumar dos números naturales. Algoritmo de suma escolar, por columnas Algoritmo de sucesor n veces. Los tres algoritmos para distintas operaciones primitivas: I sumar dos dı́gitos y acarreo, y concatenar resultados. I sumar uno, restar uno y comparar por 0. I apretar una tecla de una calculadora. 9 Definición de programa 10 Fue en los años 1930. . . Definición: Un programa es la descripción de un algoritmo en un lenguaje de programación. Alonzo Church, define el cáculo lamdba “An Unsolvable Problem of Elementary Number Theory”, American Journal of Mathematics, 1936 “A Note on the Entscheidungsproblem”, Journal of Symbolic Logic, 1936. ¿El programa siempre termina? Alan Turing, define máquina universal y demuestra sus limitaciones. ¿Es correcto? Es decir, ¿resuelve el problema? “On computable numbers with an application to the Entscheidungsproblem”, Journal of the London Mathematical Society, 1936. 11 12 Algoritmos y Estructuras de Datos I Algoritmos y Estructuras de Datos I Contenidos 1. Especificación de problemas I Lenguaje formal cercano a la lógica proposicional Objetivos El principal: aprender a programar I Especificar problemas I I describirlos en lenguaje no ambiguo, formal 3. Estructuras de datos I Especificación de tipos de datos I Implementación de tipos mediante estructuras de datos Escribir programas sencillos I I 2. Introducción a la programación imperativa I Semántica por transformación de estados I Correctitud para especificación dada tratamiento de secuencias 4. Algoritmos sobre secuencias I Búsqueda lineal I Búsqueda binaria I Algortimos de ordenamiento I Intercalación ordenada (merge) y otros con dos secuencias Razonar acerca de estos programas I I I visión abstracta del cómputo manejo simbólico y herramientas para demostrar propiedades correctitud de un programa respecto de su especificación 5. Noción de complejidad tiempo. 6. Algoritmos y estructuras de datos dinámicas. 13 Problemas y soluciones 14 Especificación, algoritmo, programa 1. especificación = descripción del problema I I I Si vamos a escribir un programa, es porque hay un problema a resolver. I necesitamos describirlo de manera precisa I no siempre es claro que haya solución I ¿qué problema tenemos? en lenguaje formal es un contrato que da las propiedades de los datos de entrada y las propiedades de la solución Edsger Dijkstra, C.A.R. Hoare (años 70) 2. algoritmo = descripción de la solución escrita para humanos I ¿cómo resolvemos el problema? 3. programa = descripción de la solución para la computadora I I 15 también, ¿cómo resolvemos el problema? usando un lenguaje de programación 16 Etapas en el desarrollo de programas especificación: diseño: programación: validación: mantenimiento: E 1. Especificación El planteo inicial del problema puede ser vago y ambiguo. Al especificar damos una descripción clara y precisa en lenguaje formal, por ejemplo, el lenguaje de la lógica matemática. Ejemplo, el problema calcular de edad de una persona, es vago porque: definición formal del problema elegir una solución y dividir el problema en partes dar algoritmos e implementarlos en algún lenguaje testear y demostrar que el programa cumple con la especificación. corregir errores y adaptarlo a nuevos requerimientos. D P V M ··· I ¿Cuáles son los datos? fecha de nacimiento, ADN I ¿Qué forma van a tener? dı́as, años enteros, fracción de años I ¿Cómo recibo los datos? manualmente, archivo en disco, sensor I ¿Cómo devuelvo el resultado? pantalla, papel, voz alta, email Una especificación formaliza algunas, como: I Necesito una función que, dadas dos fechas en formato dd/mm/aaaa, de la cantidad de dı́as que hay entre ellas. 17 2. Diseño 18 3. Programación (algoritmos) Escribir un algoritmo para dar solución a cada problema: I ¿Varios programas o uno muy complejo? ¿distintas partes en distintas máquinas? I I Asumimos que están definidos los pasos primitivos I Dar la sucesión de pasos para resolver cada problema Ejemplo: Dadas dos fechas a y b en formato dd/mm/aaaa, calcular la cantidad de dı́as que hay entre ellas. Un algoritmo es: ¿cómo dividirlo en partes? I I 1. restar el año de b al año de a (mini) especificación de cada parte un programador recibe una sola (o una por vez) 2. multiplicar el resultado por 365 3. sumarle la cantidad de dı́as desde el 1◦ de enero del año de b hasta el dı́a b ¿Programas ya hechos con los que interactuar? 4. restarle la cantidad de dı́as desde el 1◦ de enero del año de a hasta el dı́a a Estos son temas de Algoritmos y Estructuras de Datos II y de Ingenierı́a del Software I. 5. sumarle la cantidad de 29 de febrero que hubo en el perı́odo ¿Son todos pasos primitivos? I 19 si no, hay que dar algoritmos para realizarlos (Por ej. para 3, 4 y 5). 20 3. Programación (algoritmos) 3. Programación (estructuras de datos) La elección del algoritmo viene junto con la elección de una representación de los datos. I traducir el algoritmo (escrito o idea) para que una computadora lo entienda I lenguaje de programación I I I Ejemplos I Haskell (ya saben) Java (vamos a ver en esta materia) I I hay muchos otros I I Para el problema de calcular la edad de una persona, es posible representar los datos como pueden ser más adecuados para ciertas tareas depende del algoritmo, de la interfaz, tiempo de ejecución, tipo de máquina, interoperabilidad, entrenamiento de los programadores, licencias, etc. dı́as, meses, años, fracciones de año, etc. Para el problema contar la cantidad de alumnos de cada género podrı́amos usar I foto, nombre, ADN, etc. Una vez elegida la representación de los datos, es necesario elegir una estructura de datos computacional, que será usada por los algoritmos. En un tema de estudio en Algoritmos y Estructuras de Datos II. 21 4. Validación 22 5. Mantenimiento Asegurarse de que un programa cumple con la especificación Testeo I probar el programa con muchos datos y chequear la especificación. I si hay un error, con algo de suerte uno puede encontrarlo I no es infalible (puede pasar el testing pero haber errores). Para garantizar corectitud, deberı́a probar infinitos datos de entrada. I I I Las técnicas de testeo son un tema de Ingenierı́a del Software I. Verificación formal I demostrar matemáticamente que un programa cumple con una especificación. Se llama “correctitud de un programa respecto de una especificación”. Requiere que el lenguaje de especificación sea formal y admita una teorı́a de prueba, y una semántica. I una demostración cubre infinitos valores de entrada (abstracción) I es infalible (si está demostrado, el programa no tiene errores) En esta materia vamos a estudiar cómo demostrar la correctitud de programas sencillos para problemas sencillos. tiempo después, encontramos errores I o cambian los requerimientos I puede hacerlo el mismo equipo u otro I justifica las etapas anteriores I 23 el programa no cumplı́a la especificación la especificación no describı́a correctamente el problema si se hicieron bien la especificación, diseño, programación y validación, las modificaciones van a ser más sencillas y menos frecuentes 24 Lenguaje naturales y lenguajes formales Especificación de problemas Lenguajes naturales I idiomas (castellano) I mucho poder expresivo (modos verbales –potencial, imperativo–, tiempos verbales –pasado, presente, futuro—, metáforas, etc. ) I con un plus (conocimiento del contexto, experiencias compartidas, ambigüedad e imprecisión) Es un contrato que define qué se debe a resolver y qué propiedades debe tener una solución: I define el qué y no el cómo No usamos problemas para especificar problemas. Lenguajes formales I limitan lo que se puede expresar I todas las suposiciones quedan explı́citas I relación directa entre lo escrito (sintaxis) y su significado (semántica) I pueden tratarse formalmente I sı́mbolos manipulables directamente I las manipulaciones son válidas también para el significado I ejemplo: aritmética I lenguaje formal para los números y sus operaciones I resolvemos problemas simbólicamente sin pensar en los significados numéricos y llegamos a resultados correctos Es un tema de Teorı́a de Lenguajes y de Lógica y Computabilidad. Después de programar la especificación de problemas sirve para: I testing I verificación formal de correctitud I derivación formal (construir un programa a partir de la especificación) 25 Parámetros de un problema I ejemplo de problema: arreglar una cafetera I para solucionarlo, necesitamos más datos I I I Problemas funcionales ¿qué clase de cafetera es? ¿qué defecto tiene? ¿cuánto presupuesto tenemos? I se llaman parámetros del problema I los valores de los parámetros se llaman argumentos I cada combinación de valores de los parámetros es una instancia del problema 26 I no podemos especificar formalmente cualquier problema I simplificación (para esta materia) I problemas que puedan solucionarse con una función I I I parámetros de entrada un resultado para cada combinación de valores de entrada una instancia: “arreglar una cafetera de filtro cuya jarra pierde agua, gastando a lo sumo $30” 27 28 Tipos de datos Contratos Una especificación es un contrato entre el programador de una función que resuelva el problema y el usuario de esa función. Cada parámetro tiene un tipo de datos I Ejemplo de problema: calcular la raı́z cuadrada de un real conjunto de valores para los que hay ciertas operaciones definidas. Cada tipo de datos lleva un nombre. I Especificación de una función I Por ejemplo: I parámetros de tipo fecha I I I I I valores: ternas de números enteros operaciones: comparación, obtener el año,... Para hacer el cálculo, debe recibir un número no negativo I I parámetros de tipo dinero I I I valores: números reales con dos decimales operaciones: suma, resta,... con un un argumento real va a calcular un resultado real obligación del usuario: no puede proveer números negativos derecho del programador de la función: puede suponer que el argumento recibido no es negativo. El resultado va a ser la raı́z cuadrada del número. I I obligación del programador: debe calcular la raı́z, siempre y cuando haya recibido un número no negativo derecho del usuario: puede suponer que el resultado va a ser correcto 30 29 Partes de una especificación (contrato) El contrato El programador va a hacer un programa P tal que si el usuario suministra datos que hacen verdadera la precondición, entonces P va a terminar en una cantidad finita de pasos y va a devolver un valor que hace verdadera la poscondición. Tiene 3 partes 1. encabezado 2. precondición I I I I condición sobre los argumentos el programador da por cierta lo que requiere la función para hacer su tarea por ejemplo: “el valor de entrada es un real no negativo” El programa P es correcto para la especificación dada por la precondición y la postcondición exactamente cuando se cumple el contrato. Si el usuario no cumple la precondición y P se cuelga o no cumple la poscondición... 3. poscondición I I I I condición sobre el resultado debe ser cumplida por el programador, siempre y cuando el usuario haya cumplido la precondición lo que la función asegura que se va a cumplir después de llamarla (si se cumplı́a la precondición) por ejemplo: “la salida es la raı́z cuadrada del valor de entrada” I ¿el usuario tiene derecho a quejarse? No. I ¿Se cumple el contrato? Sı́. El contrato prevé este caso y dice que P solo debe funcionar en caso de que el usuario cumpla con la precondición Si el usuario cumple la precondición y P se cuelga o no cumple la poscondición... 31 I ¿el usuario tiene derecho a quejarse? Sı́. I ¿Se cumple el contrato? No. Es el único casode violación del contrato. 32 Una especificación es un contrato Nuestro lenguaje de especificación Contrato: El programador va a hacer un programa P para una especificación E tal que si el usuario suministra datos que hacen verdadera la precondición, entonces el programa P va a terminar en una cantidad finita de pasos y va a arrojar un valor que hace verdadera la poscondición. http://www.dc.uba.ar/materias/aed1/2014/1c/descargas/apuntes/AEDI-LE.pdf P es correcto para la especificación dada por la precondición y la postcondición cuando se cumple el contrato. 34 33 Encabezado de un problema Ejemplos problema rcuad(x : Float) = result : Float { requiere x ≥ 0; asegura result ∗ result == x; } problema nombre(parámetros) = nombreRes : tipoRes I problema suma(x : Int, y : Int) = result : Int { asegura result == x + y ; } nombre: nombre que le damos al problema I será resuelto por una función con ese mismo nombre I nombreRes: nombre que le damos al resultado I tipoRes: tipo de datos del resultado I parámetros: lista que da el tipo y el nombre de cada uno problema resta(x : Int, y : Int) = result : Int { asegura result == x − y ; } problema cualquieramayor (x : Int) = result : Int { asegura result > x; } 35 36 Argumentos que se modifican (modifica y usa pre()) Otro ejemplo Dado dos enteros dividendo y divisor, obtener el cociente entero problema cociente(dividendo : Int, divisor : Int) = result : Int { requiere divisor > 0; asegura (result ∗ divisor ≤ dividendo) asegura ((result + 1) ∗ divisor > dividendo) } La especificación anterior es la función haskell div or mod. Notar div (-5) 3 == -2 mod (-5) 3 == 1 div 5 (-3) == -2 mod 5 (-3) == -1 div (-5) (-3) == 1 mod (-5) (-3) == -2 Problema: Incrementar en uno el argumento de entrada. Alternativa sin modifcar la entrada (usual). problema incremento(a : Int) = res : Int{ asegura res == a + 1; } Alternativa que modifica la entrada: usamos el mismo argumento para la entrada y para la salida. I problema incremento-modificando(a : Int){ modifica a; asegura a == pre(a) + 1; } cociente:: Int -> Int -> Int cociente x y | (x < y) = 0 cociente x y | (x >= y) = 1 + (cociente (x-y) y) I cociente 1 0: No termina (pero no viola la especificación). Observar que en este caso la función no tiene un resultado en su nombre. I cociente (-4) (-2) == 0. Viola la especificación. I cociente 4 (-2): No termina. Viola la especificación. 37 Argumentos de salida (modifica, no usa pre()) 38 Dos argumentos de salida (modifica, no usa pre) Problema: Calcular el cociente y el resto Problema: Calcular el cociente y el resto I Cociente: el resultado de la función. I Cociente y resto: ambos argumentos modificables I Resto: argumento modificable. I La función no tiene resultado en su nombre. problema cocienteModificaResto(a, b, r : Int) = q : Int { requiere b > 0; modifica r ; asegura a == q ∗ b + r ∧ 0 ≤ r < b; } problema ModificaCocienteYModificaResto(a, b, q, r : Int){ requiere b > 0; modifica q, r ; asegura a == q ∗ b + r ∧ 0 ≤ r < b; } 39 40 Sobrespecificación Subespecificación Dar una postcondición más restrictiva que lo que se necesita o una precondición más laxa Dar una una precondición más restrictiva o postcondición más débil. I I Limita excesivamente los posibles algoritmos que resuelven el problema, porque impone más condiciones para la salida, o amplı́a los datos de entrada. Deja afuera datos de entrada o ignora condiciones necesarias para la salida (permite soluciones no deseadas). Ejemplo de subespecificación: problema distinto(x : Int) = res : Int { requiere x > 0; asegura not(res == x) } Ejemplo de sobrespecificación: problema distinto(x : Int) = res : Int { asegura res == x + 1; } en vez de problema distinto(x : Int) = res : Int { asegura not(res == x) } en vez de : problema distinto(x : Int) = res : Int { asegura not(res == x) } 42 41 Especificar los siguientes problemas I Calcular la función signo problema signo(x : Float) = r : Int { asegura(r == 0 ∧ x == 0) ∨ (r == −1 ∧ x < 0) ∨ (r == 1 ∧ x > 0) } I Calcular el área de un triángulo rectángulo problema area(x, y : Float) = r : Float { requiere x > 0 requiere y > 0 asegura r == x ∗ y /2 } I Encontrar una raı́z para un polinomio de grado 2 problema raizPolinmioGrado2(a, b, c : Float) = r : Int { requiere a 6= 0 requiere b ∗ b ≥ 4 ∗ a ∗ c asegura a ∗ r ∗ r + b ∗ r + c == 0 } Especificar el siguientes problema: Dada una hora,minutos y segundos correspindientes a una hora de la mañana, dar la cantidad de segundos que faltan hasta mediodı́a. problema hastamediodia(h, m, s : Int) = r : Int { requiere 0 ≤ h < 12 requiere 0 ≤ m < 60 requiere 0 ≤ s < 60 asegura r + (h ∗ 60 + m) ∗ 60 + s == 12 ∗ 60 ∗ 60 } 43 44 Lógica proposicional - sintaxis I sı́mbolos true , false , ⊥ , ¬ , ∧ , ∨ , → , ↔ , ( , ) I Lógica proposicional variables proposicionales (infinitas) p , q , r , ... I fórmulas 1. true, false y ⊥ son fórmulas 2. cualquier variable proposicional es una fórmula 3. si A es una fórmula, ¬A es una fórmula 4. si A1 , A2 , . . . , An son fórmulas, (A1 ∧ A2 ∧ · · · ∧ An ) es una fórmula 5. si A1 , A2 , . . . , An son fórmulas, (A1 ∨ A2 ∨ · · · ∨ An ) es una fórmula 6. si A y B son fórmulas, (A → B) es una fórmula 7. si A y B son fórmulas, (A ↔ B) es una fórmula 46 45 Semántica clásica I Semántica clásica 2 valores de verdad posibles Conociendo el valor de las variables proposicionales de una fórmula, conocemos el valor de verdad de la fórmula 1. verdadero (1) 2. falso (0) I p 1 0 El valor de verdas de una fórmula se obtiene a partir del valor de verdad de sus subfórmulas. I I I I I I I true siempre vale 1 false siempre vale 0 ¬A se interpreta como “no”, se llama negación ∧ se interpreta como “y”, se llama conjunción ∨ se interpreta como “o”(no exclusivo), se llama disyunción → se interpreta como “si... entonces”, se llama implicación ↔ se interpreta como “si y solo si”, se llama doble implicación o equivalencia p 1 1 0 0 47 p 1 1 0 0 ¬p 0 1 q 1 0 1 0 (p → q) 1 0 1 1 q 1 0 1 0 (p ∧ q) 1 0 0 0 p 1 1 0 0 p 1 1 0 0 q 1 0 1 0 q 1 0 1 0 (p ∨ q) 1 1 1 0 (p ↔ q) 1 0 0 1 48 Ejemplo: tabla de verdad para ((p ∧ q) → r ) p 1 1 1 1 0 0 0 0 q 1 1 0 0 1 1 0 0 r 1 0 1 0 1 0 1 0 (p ∧ q) 1 1 0 0 0 0 0 0 Un ejercicio Escribir la siguiente frase como una fórmula de lógica proposicional. ((p ∧ q) → r ) 1 0 1 1 1 1 1 1 “Si Juan está cursando y no conoce a nadie entonces Juan todavı́a no tiene grupo” I Solución: p = Juan está cursando q= Juan no conoce a nadie r = Juan no tiene grupo (p ∧ q) =⇒ r 50 49 Otro ejercicio Oro ejercicio más “Si Juan está cursando y no conoce a nadie entonces Juan todavı́a no tiene grupo” Sea p = Juan está cursando; q= Juan no conoce a nadie; r = Juan no tiene grupo. ¿ Cuáles de las siguientes son una especificación adecuada para el el problema de decidir si un número entero es positivo? (p ∧ q) =⇒ r . problema esPositivo (x : Int) = r : Bool Esta fórmula es equivalente a una sola de las siguientes. ¿A cuál? 1. asegura(x > 0 ∧ r == true)} 1. Si Juan está cursando entonces no tiene grupo. Solución (p =⇒ q) 2. asegura(x > 0 ∧ r == true) ∧ (x <= 0 ∧ r == false)} 3. asegura(x > 0 ∧ r == true) ∨ (x <= 0 ∧ r == false)} 2. Si Juan no tiene grupo entonces Juan no conoce a nadie. Solución (r =⇒ q) 4. asegura(x > 0 =⇒ r == true)} 3. Si Juan está cursando y no tiene grupo entonces Juan no conoce a nadie. Solución (p ∧ r ) =⇒ q 5. asegura(x > 0 =⇒ r == true) ∨ (x <= 0 =⇒ r == false)} 4. Si Juan no conoce a nadie entonces está cursando y no tiene grupo. Solución q =⇒ (p ∧ r ) 6. asegura(x > 0 =⇒ r == true)∧} 5. Si Juan no conoce a nadie entonces está cursando o no tiene grupo. Solución q =⇒ (p ∨ r ) 8. asegura(x <= 0 ⇐⇒ r == false)} 7. asegura(x > 0 ⇐⇒ r == true)} Solución: La número 3 es adecuada. Y las que son equivalentes a la postcondición dada en 3. Descubrirlas escribir las postcondiciones como fórmulas de tipo Bool y hacer las tablas de verdad usando, p : (x > 0), q : (r == true). Notar que (¬p) : (x <= 0) y (¬q) : (r == false) 6. Si Juan tiene grupo entonces Juan conoce a alguien. Solución ¬r =⇒ ¬q 7. Si Juan tiene grupo entonces es imposible que esté cursando y no conozca a nadie Solución ¬r =⇒ ¬(p ∧ q) 51 52
Puede agregar este documento a su colección de estudio (s)
Iniciar sesión Disponible sólo para usuarios autorizadosPuede agregar este documento a su lista guardada
Iniciar sesión Disponible sólo para usuarios autorizados(Para quejas, use otra forma )