Transparencias nuevas (formato PDF)
Transcripción
Transparencias nuevas (formato PDF)
Tecnología de la Programación (ETIX) Pedro Cabalar Depto. de Computación Universidade da Coruña [email protected] curso 2009/2010 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 1 / 145 Guión 1 Introducción 2 Tema 2. Lógica Cálculo Proposicional Cálculo de Predicados 3 Arrays 4 Guarded Command Language 5 Aserciones 6 Verificación formal de programas 7 Derivación de programas 8 Construcción de invariantes 9 Funciones cota 10 Procedimientos, funciones y recursividad Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 2 / 145 Un poco de historia . . . Edsger W. Dijkstra 1930 – 2002 Sir C. Anthony R. Hoare 1934 – Hasta finales 60’s: programas indescifrables, saltos tipo go to. Programación estructurada [Böhm & Jacopini 66]: cualquier programa = secuencia + condicional + iteración. E. W. Dijkstra Go To Statement Considered Harmful, [1968]. Tony Hoare diseña el Quicksort [1962] Lógica de Hoare [1969] (semántica axiomática) [Dijkstra 1976] A Discipline of Programming: verificación formal, weakest precondition, derivación de programas Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 3 / 145 Verificación Formal Método ensayo y error Verificación formal Nunca confianza 100 % Corrección por prueba matemática Clave: diseñar bien los casos de prueba Clave: formular las propiedades a probar Siempre dependo del programa Puedo trabajar sobre el algoritmo Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 4 / 145 Verificación Formal Verificación formal Programa + fórmulas −→ ¿Correcto? I I Sí : prueba de corrección No : contraejemplo Especificación formal: expresar bien las fórmulas precondición y postcondición. Necesario: dotar de semántica al lenguaje de programación. Derivación de programas: fórmulas + prueba de corrección −→ programa Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 5 / 145 Especificación formal Ejemplo de importancia de especificar bien. Calcular el resto r y el cociente c de x/y { y>0 and x>=0 } precondición r:=x; c:=0; while r>y do begin r:=r-y; c:=c+1 end { x=y*c+r and r<y } postcondición Problema: con x=6, y=3 . . . c=1, r=3. Nuevo problema: obtenemos un r=-2 con x=-2 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 6 / 145 Ejercicio 1 Queremos calcular el mcd(a,b) donde a > b ≥ 0 Algoritmo de Euclides: n:=a; d:=b; while d<>0 do begin r:=n mod d; n:=d; d:=r; end; ¿Puedes demostrarme que funciona? Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 7 / 145 Ejercicio 2 Un programa genera esta secuencia . . . 1 11 21 1211 111221 312211 13112221 1113213211 Parece que sólo genera números entre 1 y 3: “lo he ejecutado 200 veces y parece que es así . . . ” “Mmmm, 0,5 puntos a que no me lo demuestras” Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 8 / 145 Ejercicio 3 El profesor de Johan Carl Friedich Gauss decide castigarlo por hablar en clase haciéndole sumar los números del 1 al 100. Si Gauss programase en Pascal . . . const n=100; i:=1; s:=0; while i<=n do begin s:=s+i; i:=i+1; end; Pero se dio cuenta enseguida de que se puede reemplazar por una simple fórmula. Resultado = 5050. Dado n ≥ 0 ¿puedes demostrar que el programa anterior es equivalente a este? i:= ?? ; s:= ?? ; Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 9 / 145 Cálculo Proposicional Sintaxis Partimos de un conjunto de identificadores, ID (ejemplo: ID = {x, y , r , c}) Definición (Fórmula proposicional) Cualquiera de las expresiones: i) T v) α ∨ β ix) (α) ii) F vi) α ∧ β iii) p vii) α ⇒ β iv) ¬α viii) α = β donde p identificador y α, β fórmulas prop. Precedencia: ‘¬’ < ‘ ∧ ’ < ‘ ∨ ’ < ‘ ⇒ ’ < ‘ = ’ (los binarios son de izquierda a derecha) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 11 / 145 Semántica Definición (Estado) Un estado s es una función del tipo: s : ID −→ {T , F } también representable como cjto. de pares (id, valor ). Ejemplo: si s = {(x, T ), (y , F ), (r , F ), (c, T )} entonces s(x) = T , s(y ) = F , etc. Ampliamos el uso de s(·) a cualquier fórmula proposicional. Definición (Función de evaluación) s(α) se obtiene reemplazando todo p en α por s(p) y aplicando las tablas: b c ¬b b ∧ c b ∨ c b ⇒ c b = c F F T F F T T F T T F T T F T F F F T F F T T F T T T T Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 12 / 145 Semántica Definición (Tautología) Cualquier fórmula α tal que, para todo s, s(α) = T . Ejemplos: T , p ∨ ¬p, b ∧ c ∧ d ⇒ (d ⇒ b) Probar que α es tautología = probar todos los estados. Probar que no lo es = encontrar un contraejemplo Definición (Inconsistencia) Cualquier fórmula α tal que, para todo s, s(α) = F . α es tautología si y sólo si ¬α es inconsistente Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 13 / 145 Semántica Alternativa: una fórmula α representa un conjunto de estados EST (α) (los que la hacen cierta). EST (F ) = ∅ EST (T ) = S (todos los posibles) EST (a ∨ b) = {{(a, T ), (b, T )}, {(a, T ), (b, F )}, {(a, F ), (b, T )}} A menudo identificaremos α con EST (α) y viceversa. A partir de un conjunto de estados: ¿ Cómo obtener la fórmula que los representa? Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 14 / 145 Semántica Definición (Fórmula más débil/más fuerte) Si α ⇒ β es un tautología, es decir, si EST (α) ⊆ EST (β), entonces α es más fuerte que β (o β más débil que α). ¿ Cuáles son las fórmulas más fuerte y más débil posibles? Ejemplos p p p∨q p p ∧ ¬q ⇐ ⇒ ⇐ ⇒ p∧q p ∨ ¬q p∧q (q ⇒ p) ¬p ∧ q Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 15 / 145 Métodos de prueba: encadenar equivalencias Regla de sustitución uniforme Si α = β es tautología y α es subfórmula de γ, escrito como γ(α), entonces γ(α) = γ(β) es tautología. Ejemplo: γ : a ∧ ¬(b ∨ c) α : ¬(b ∨ c) β : ¬b ∧ ¬c a ∧ ¬(b ∨ c) = a ∧ ¬b ∧ ¬c Regla de transitividad Si α = β y β = γ son tautologías, entonces también lo es α = γ. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 16 / 145 Algunas tautologías para cualesquiera α y β Conmutatividad 1) α ∧ β = β ∧ α 2) α ∨ β = β ∨ α 3) (α = β) = (β = α) Distributividad 6) α ∨ (β ∧ γ) = (α ∨ β) ∧ (α ∨ γ) 7) α ∧ (β ∨ γ) = (α ∧ β) ∨ (α ∧ γ) Simplificación 10) α ∨ α = α 11) α ∧ α = α 12) α ∨ T = T 13) α ∨ F = α 14) α ∧ T = α 15) α ∧ F = F 16) α ∨ (α ∧ β) = α 17) α ∧ (α ∨ β) = α Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) Asociatividad 4) α ∨ (β ∨ γ) = (α ∨ β) ∨ γ 5) α ∧ (β ∧ γ) = (α ∧ β) ∧ γ Leyes de De Morgan 8) ¬(α ∧ β) = ¬α ∨ ¬β 9) ¬(α ∨ β) = ¬α ∧ ¬β Otras 18) α = α 19) ¬¬α = α 20) α ∨ ¬α = T 21) α ∧ ¬α = F 22) α ⇒ β = ¬α ∨ β 23) (α = β) = (α ⇒ β) ∧ (β ⇒ α) 24) ¬T = F , T ∧ F = F , etc curso 2009/2010 17 / 145 Métodos de prueba: encadenar equivalencias Ejemplo: probar (α ⇒ β) = (¬β ⇒ ¬α) Ejemplo: probar la regla de contradicción (21) a partir de las restantes. Otras tautologías que usaremos con frecuencia 25) (α ⇒ β) ⇒ (α ∧ β) = α 26) (α ⇒ β) ⇒ (α ∨ β) = β 27) α ∨ ¬α ∧ β = α ∨ β Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 18 / 145 Del lenguaje natural al formal . . . A⇒B A≡B A∨B A 6≡ B A implica B A es suficiente para B B es necesario para A si A entonces B B si A A sólo si B no A a no ser que B no A a menos que B B siempre que A A equivale a B A si y sólo si B A ó B (inclusivo) A ó B (exclusivo) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 19 / 145 Ejemplos Juan es ateo si es comunista. Juan es ateo. Luego Juan es comunista. Si acabo de comer tomo café, a no ser que haya bebido vino. Tomo café sólo si no voy a dormir siesta. Acabo de comer y voy a dormir la siesta. Luego he bebido vino. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 20 / 145 Ejemplos Debemos elegir una puerta. En cada una puede haber o un tigre o una dama. Un letrero dice la verdad y el otro no. ¿Qué puerta abrimos? 1. Aquí hay una dama y en la otra un tigre 2. En una hay una dama y en otra un tigre Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 21 / 145 Ejemplos Hay una dama y 2 tigres. Como mucho un letrero dice la verdad. ¿Qué puerta abrimos? 1. Aquí hay un tigre 2. Aquí hay una dama 3. En 2 hay un tigre Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 22 / 145 Predicados: sintaxis Por el momento, permitimos expresiones relacionales en el lugar de identificadores. Ejemplo: a ≥ b ∨ ¬(c < d) Operaciones relacionales y aritméticas predefinidas: ≤, ≥, <, >, =, 6=, +, −, ∗, / Precedencia: la habitual. Todos mayor prioridad que los lógicos. Usando terminología lógica estándar: ≤, ≥, >, <, =, 6= son predicados binarios +, −, ∗, / son funciones binarias − es una función unaria 0, 1, 2, −1, −2, T , F son nombres de constantes Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 24 / 145 Predicados: semántica Tenemos un conjunto de valores constantes: Valores = {0, 1, 2, −1, −2, T , F , ...} Definimos tipos. Cada identificador i tiene un rango de valores rango(i). Ejemplos: i : boolean i : natural i : integer def = rango(i) = {T , F } def = rango(i) = {0, 1, 2, . . . } def rango(i) = {. . . , −2, −1, 0, 1, 2, . . . } = Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 25 / 145 Predicados: semántica Definición (Estado) Un estado, s, es una función del tipo s : ID −→ Valores también representable como cjto. de pares (i, v ), de modo que v ∈ rango(i). Ejemplo: rango(x) = {0, 1, 2} y : integer b : boolean s = {(x, 0), (y , −3), (b, F )} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 26 / 145 Predicados: semántica Igual que en proposicional, ampliamos el uso de s(·) a cualquier fórmula de predicados. Definición (Función de evaluación) Dado un estado s y una fórmula α, s(α) se obtiene reemplazando todo x en α por s(x) y aplicando las operaciones predefinidas ≤, ≥, <, >, +, ∗, etc. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 27 / 145 Predicados: semántica Ejemplos: dado s = {(x, 0), (y , −3), (b, F )} s( x > y ∧ ¬b ) s( b ∨ x + y = −3 ⇒ y + 3 = 2 ∗ x ) s( x = y = b ) s( x 6= 0 ∧ y /x = 2 ) Problema: la expresión debería ser F pero: ¿ quién es −3/0? Introducimos un nuevo valor: U (“undefined"). Para cualquier k , s(k /0) = U En todas las tablas de operadores vistas, si al menos un operando es U, entonces el resultado es U también. Ejemplos: s(−U) = U, s(3 ∗ U) = U, s(F ∨ U) = U, s(¬U) = U Ejemplo: s( x/0 = y /0 ) Nunca puede darse U ∈ rango(x) o s(x) = U Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 28 / 145 Nuevos operadores α β α cand β α cor β F F F F F U F U F T F T U F U U U U U U U U U T T F F T U T T U T T T T α cand β equivale a: “si α entonces β, en otro caso F " α≡β T F F F T F F F T α cor β equivale a: “si α entonces T , en otro caso β" α ≡ β no lo usaremos dentro del programa. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 29 / 145 Nuevos operadores Probar que (α cand β ≡ β cand α) no es tautología. En cambio, sí lo son las siguientes fórmulas. Asociatividad: α cand (β cand γ) ≡ (α cand β) cand γ α cor (β cor γ) ≡ (α cor β) cor γ Distributividad: α cand (β cor γ) ≡ (α cand β) cor (α cand γ) α cor (β cand γ) ≡ (α cor β) cand (α cor γ) De Morgan: ¬(α cand β) ≡ ¬α cor ¬β ¬(α cor β) ≡ ¬α cand ¬β Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 30 / 145 Nuevos operadores Simplificaciones: α cor α ≡ α α cor F ≡ α α cor (α cand β) ≡ α α cand α ≡ α α cand T ≡ α α cand (α cor β) ≡ α Si s(α) 6= U entonces: α cor T ≡ T α cand F ≡ F α cor ¬α ≡ T α cand ¬α ≡ F En general, cualquier equivalencia con ∧, ∨ es aplicable a cand , cor , si se respeta el orden de las subfórmulas. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 31 / 145 Cuantificadores Consideremos expresiones del estilo: αm ∨ αm+1 ∨ · · · ∨ αn−1 (1) donde αI son fórmulas de predicados que pueden hacer referencia al valor constante I. Abreviamos (1) como: (∃I : m ≤ I < n : αI ) Ejemplo: la fórmula (∃I : 2 ≤ I < 6 : x = y ∗ I) es lo mismo que: x = y ∗ 2 ∨ x = y ∗ 3 ∨ x = y ∗ 4 ∨ x = y ∗ 5 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 32 / 145 Cuantificadores Algunas abreviaturas: 1 Varias variables índice. Ejemplo: (∃I, J : 5 ≤ I, J < 7 : 2 ∗ I + x ≤ J) = (∃I : 5 ≤ I < 7 : (∃J : 5 ≤ J < 7 : 2 ∗ i + x ≤ j)) 2 Uso de intervalos [m, n) o [m, n − 1]: (∃I ∈ [m, n) : αI ) = (∃I : m ≤ I < n : αI ) Correspondencia con notación clásica: ∃ I (m ≤ I ∧ I < n ∧ αI ) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 33 / 145 Cuantificadores ¡Mucho cuidado!: I I Los cuantificadores no son parte del programa. Sólo aparecen en las condiciones entre llaves. La variable cuantificada no es un identificador del programa. Es como una abreviatura de todos sus valores [m, n − 1]. Usaremos: MAYÚSCULAS = variables cuantificadas y constantes, minúsculas = identificadores del programa. Definición recursiva del ∃: ∃I∈[m,k +1):αI ∃I∈[m,k ):αI z }| { z }| { α1 ∨ · · · ∨ αk −1 ∨ αk = α1 ∨ · · · ∨ αk −1 ∨αk 1 2 (∃I ∈ [m, k + 1) : αI ) = (∃I ∈ [m, k ) : αI ) ∨ αk , para k ≥ m. (∃I ∈ [m, m) : αI ) = F Caso 2: con rango vacío equivale a falso F Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 34 / 145 Cuantificadores Cuantificador universal ∀: análogo del ∃. ∀I ∈ [m, n) : αI = ¬ ∃I ∈ [m, n) : ¬αI = ¬(¬αm ∨ ¬αm+1 ∨ · · · ∨ ¬αn−1 ) = αm ∧ αm+1 ∧ · · · ∧ αn−1 ¿ A qué equivale ∀I ∈ [m, m) : αI ? ¿ Quién es ∀I ∈ [m, n) : αI en notación clásica? ∀I(m ≤ I ∧ I < n ⇒ αI ) (demostrarlo) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 35 / 145 Variables libres y ligadas Las variables de cuantificación son locales a la expresión cuantificada. ∃I ∈ [2, 5) : I = 3 ∗ x ∧ ∀I ∈ [1, 10) : f (I) = 0 ∧ f (I) < 2 Cambiar su nombre no afecta a cómo son interpretadas. Imaginemos s = {(x, 1), (y , 2)} y consideremos: ∃I ∈ [2, 5) : I = 3 ∗ x ∃J ∈ [2, 5) : J = 3 ∗ x ∃I ∈ [2, 5) : I = 3 ∗ y ∃x ∈ [2, 5) : x = 3 ∗ x Problema : ojo si usamos un nombre que existía. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 36 / 145 Variables libres y ligadas Definición (Variable ligada) Una variable i se dice que está ligada en una expresión α, si aparece al menos una vez en α dentro del ámbito de algún cuantificador (∃i ó ∀i). Definición (Variable libre) Una variable i se dice que está libre en una expresión α, si aparece al menos una vez en α fuera del ámbito de ningún cuantificador (∃i o ∀i). Ejemplo: ¿ qué ocurre con la fórmula de abajo? i < 2 ∧ ∃i ∈ [m, n) : i = 2 ∗ x Cuidado: i puede estar simultáneamente libre y ligada en α. Para evitar confusión, podemos renombrar la ligada i < 2 ∧ ∃J ∈ [m, n) : J = 2 ∗ x Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 37 / 145 Variables libres y ligadas Más ejemplos: 2 ≤ m < n ∧ ∀i ∈ [2, m) : m/i 6= 0 2 ≤ m < n ∧ ∀n ∈ [2, m) : m/n 6= 0 ∃i ∈ [1, 25) : 25/i = 0 ∧ ∃i ∈ [1, 25) : 26/i = 0 ∃t ∈ [1, 25) : 25/t = 0 ∧ ∃i ∈ [1, 25) : 26/i = 0 ∃i ∈ [1, 25) : 25/i = 0 ∧ 26/i = 0 ∀m ∈ [n, n + 6) : ∃i ∈ [2, m) : m/i = 0 ∀m ∈ [n, n + 6) : ∃n ∈ [2, n) : m/n = 0 ∃k ∈ [0, n) : P ∧ Hk (T ) ∧ k > 0 ∀j ∈ [0, n) : ∃t ∈ [j + 1, m) : ∀k ∈ [0, n) : F (k , t) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 38 / 145 Sustitución textual Definición (Sustitución textual) αex se obtiene sustituyendo en la expresión α todas las apariciones libres del identificador x por la expresión e. Ejemplos: (x ∗ y )xz (x ∗ y )xx+1 = (z ∗ y ) = ((x + 1) ∗ y ) Será usada para las instrucciones de asignación. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 39 / 145 Sustitución textual Sea α la expresión: α : x < y ∧ ∃I ∈ [0, n) : I + x < y ∨ b más ejemplos: αzx = z<y∧ ∃I ∈ [0, n) : I + z < y ∨ b y αx+y = x <x +y ∧ ∃I ∈ [0, n) : I + x < x + y ∨ b y (αw∗z )za+u = (x < w ∗ z ∧ ∃I ∈ [0, n) : I + x < w ∗ z ∨ b)za+u = x < w ∗ (a + u) ∧ ∃I ∈ [0, n) : I + x < w ∗ (a + u) ∨ b αkI = α Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 40 / 145 Sustitución textual Restricciones: Las variables libres en e no pueden convertirse en ligadas en αex . Para evitarlo, renombrar la ligada en α. Ejemplo: αIx = I < y ∧ ∃J ∈ [0, n) : J + I < y ∨ b La expresión αex debe ser correcta semánticamente. Ejemplo: α3b = x < y ∧ ∃J ∈ [0, n) : J + I < y ∨ 3 (c[i])c3 = 3[i] son sustituciones no válidas (semánticamente). Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 41 / 145 Sustitución textual n Definimos αex11,...,x ,...,en como la sustitución simultánea de las xi por las expresiones ei . Ejemplos: (x + y )x,y 3,c (x + y )x,y y +1,c x ((x + y )y +1 )yc = 3+c = y +1+c = c+1+c x,y En general: αu,v 6= (αux )yv . Poned un ejemplo. Mismas restricciones que para el caso simple: 1 2 no ligar variables libres en las ei αex debe ser semánticamente correcta Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 42 / 145 Sustitución textual Def. El estado (s; x : v ) es igual a s, excepto que x pasa a valer v : s − {(x, . . . )} ∪ {(x, v )} ¿ Quiénes son los estados de αex respecto a los de α? Una asignación x := e aplicada en s resultará en (s; x : s(e)). ¿ Quién es (s; x : s(x))? Propiedades: x i) s(αex ) = s(αs(e) ) 0 ii) Sea s = (s; x : s(e)). Entonces s0 (α) = s(αex ) iii) Dadas dos listas de identificadores x y u mutuamente excluyentes: (αux )ux = α Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 43 / 145 Sustitución textual Dado s = {(x, 5), (y , 6), (b, T )} calcular los estados: 1 (s; x : 6) 2 (s; y : s(x)) 3 (s; y : s(x + y )) 4 (s; b : x = 6) 5 ((s; x : 6); y : 4) 6 ((s; x : y ); y : x) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 44 / 145 Algunas propiedades Eliminación de condición a la izquierda del ’:’ ∀I ∈ [m, n) ∧ αI : βI ≡ ∀I ∈ [m, n) : αI ⇒ βI ∃I ∈ [m, n) ∧ αI : βI ≡ ∃I ∈ [m, n) : αI ∧ βI De Morgan: ¬ ∀I ∈ [m, n) ∧ αI : βI ≡ ∃I ∈ [m, n) ∧ αI : ¬βI ¬ ∃I ∈ [m, n) ∧ αI : βI ≡ ∀I ∈ [m, n) ∧ αI : ¬βI Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 45 / 145 Algunas propiedades Rango vacío/condición falsa: ∀I ∈ ∅ : α ≡ T ∀I ∈ [m, n) ∧ F : α ≡ T ∃I ∈ ∅ : α ≡ F ∃I ∈ [m, n) ∧ F : α ≡ F Rango unitario: ∀I ∈ {e} ∧ α : β ≡ (α ⇒ β)Ie ∃I ∈ {e} ∧ α : β ≡ (α ∧ β)Ie Distributividad: si I no libre en γ entonces ∀I ∈ [m, n) ∧ αI : γ ∨ βI ≡ γ ∨ ∀I ∈ [m, n) ∧ αI : βI ∃I ∈ [m, n) ∧ αI : γ ∧ βI ≡ γ ∧ ∃I ∈ [m, n) ∧ αI : βI Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 46 / 145 Algunas propiedades Término constante: si I no libre en γ ∀I ∈ [m, n) ∧ αI : γ ≡ ∃I ∈ [m, n) : αI ⇒ γ ∃I ∈ [m, n) ∧ αI : γ ≡ γ ∧ ∃I ∈ [m, n) : αI Si además n > m: ∀I ∈ [m, n) : γ ≡ γ ∃I ∈ [m, n) : γ ≡ γ Partición de rango: si m ≤ k < n entonces ∀I ∈ [m, n) ∧ α : β ≡ ∀I ∈ [m, k ) ∧ α : β ∧ ∀I ∈ [k , n) ∧ α : β ∃I ∈ [m, n) ∧ α : β ≡ ∃I ∈ [m, k ) ∧ α : β ∨ ∃I ∈ [k , n) ∧ α : β Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 47 / 145 Algunas propiedades Regla del término: ∀I ∈ [m, n) ∧ α : β ∧ γ ≡ ∀I ∈ [m, n) ∧ α : β ∧ ∀I ∈ [m, n) ∧ α : γ ∃I ∈ [m, n) ∧ α : β ∨ γ ≡ ∃I ∈ [m, n) ∧ α : β ∨ ∃I ∈ [m, n) ∧ α : γ Al revés ∀I ∈ [m, n) ∧ α : β ∨ γ no funciona Anidado: ∀I ∈ [m, n) : ∀J ∈ [r , s) : γI,J ≡ ∀J ∈ [r , s) : ∀I ∈ [m, n) : γI,J ∃I ∈ [m, n) : ∃J ∈ [r , s) : γI,J ≡ ∃J ∈ [r , s) : ∃I ∈ [m, n) : γI,J pero no con cuantificadores alternos ∀∃ 6≡ ∃∀ Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 48 / 145 Nuevos cuantificadores ¿Cómo expresar que k es la q-ésima raíz de f en el intervalo [0, 100)? Introducimos nuevo operador |α|. Su semántica se define como: s(|T |) = 1 s(|F |) = 0 El operador contador se define como: N I ∈ [m, n) : αI = |αm | + |αm+1 | + · · · + |αn−1 | Ejemplo: desarrollar N I ∈ [0, 5) : I m« od 2 = 0 El ejemplo se formularía como: 0 ≤ k < 100 ∧ f (k ) = 0 ∧ N I ∈ [0, k ) : f (I) = 0 = q − 1 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 49 / 145 Nuevos cuantificadores Atención: N I ∈ [m, n) : αI es una expresión entera, no una fórmula. ∀ y ∃ son definibles en función de N. ∀I ∈ [m, n) : αI ≡ N I ∈ [m, n) : αI = n − m ∃I ∈ [m, n) : αI ≡ N I ∈ [m, n) : αI ≥ 1 También podemos tener varias variables: N I ∈ [0, 3), J ∈ [0, 4) : I < J = |0 < 0| + |0 < 1| + |0 < 2| + |0 < 3| + |1 < 0| + |1 < 1| + |0 < 2| + |0 < 3| + |2 < 0| + |2 < 1| + |2 < 2| + |2 < 3| = 6 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 50 / 145 Nuevos cuantificadores Sumatorio ΣI ∈ [m, n) : αI = αm + αm+1 + · · · + αn−1 Producto ΠI ∈ [m, n) : αI = αm ∗ αm+1 ∗ · · · ∗ αn−1 No olvidar el operador de base. Por ejemplo: ¿quiénes son? N I ∈ ∅ : αI ΣI ∈ ∅ : αI ΠI ∈ ∅ : αI Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 51 / 145 Predicados y funciones auxiliares Podremos hacer uso de predicados auxiliares. Ejemplo: primo(X ) def = X : integer ∧ X > 0 ∧ ∀I ∈ [2, X ) : X m« od I 6= 0 o de funciones auxiliares como: X def abs(X ) = −X si X ≥ 0 en otro caso La definición puede ser inductiva (recursiva). Ejemplo: 1 def 1 fibo(I) = fibo(I − 1) + fibo(I − 2) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) si I = 1 si I = 2 si I > 2 curso 2009/2010 52 / 145 Arrays b[0 : 2] : integer equivale a la sentencia Pascal var b : array [0 : 2] of integer Dos formas de entender el array: 1 Son varios identificadores clasificados por un índice: b[0], b[1], b[2]. Ejemplo de estado: s = {(b[0], 4), (b[1], −2), (b[2], 7)} 2 Es un solo identificador b cuyos valores son funciones: b : {0, 1, 2} −→ integer 0 7−→ 4 1 2 7−→ 7−→ −2 7 Ejemplo de estado: s = {(b, (4, −2, 7))} Usaremos esta última alternativa. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 53 / 145 Arrays Dado b[m : n] : integer se define el predicado auxiliar: def enrango(X , b) = m ≤ X ≤ n ¿Qué efecto produce b[1] := 8? 1 2 cambiar el valor de b[1] por 8 cambiar el valor de b por (4, 8, 7) Definición El array (b; i : e) se define como: (b; i : e)[j] def = e si i = j b[j] si i 6= j Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 54 / 145 Arrays def Abreviatura (b; i : e; j : f ; k : g) = (((b; i : e); j : f ); k : g) Dado b[0 : 2] : integer y s = {(b, (4, −2, 7))} cómo se evalúan en s las siguientes expresiones: (b; 1 : 8) (b; 1 : 8)[2] (b; 1 : 8)[1] (b; 0 : 3; 1 : 5; 0 : 2; 2 : 8) (b; 0 : 3; 1 : 5; 0 : 2; 2 : 8)[0] b[15] En general, si ¬enrango(X , b) entonces s(b[X ]) = U Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 55 / 145 Arrays Predicado auxiliar perm(b, c) denota que c es permutación de b. Ejemplo: b[0 : 2] = (4, 8, 7). Entonces perm(b, c) es cierto para los valores de c: (4, 8, 7), (4, 7, 8), (8, 4, 7), (8, 7, 4), (7, 4, 8), (7, 8, 4) Ejercicio: formular perm(b, c). Ejemplo típico de simplificación: (b; i : 5)[j] = 5 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 56 / 145 Algunas abreviaturas Usaremos las abreviaturas: def = (∀I ∈ [1, 4] : b[I] = x) b[1 : 4] 6= x def = (∀I ∈ [1, 4] : b[I] 6= x) b[0 : 3] ≤ b[3 : 6] def = (∀I ∈ [0, 3], J ∈ [3, 6] : b[I] ≤ b[J]) ¬(b[1 : 4] = x) def (∃I ∈ [1, 4] : b[I] 6= x) b[1 : 4] = x = También, dados 2 arrays b[m : n] : integer y c[r : s] : integer , si n − m = s − r escribimos: def b[m : n] = c[r : s] = ∀I ∈ [0, n − m + 1) : b[I + m] = c[I + r ] Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 57 / 145 Arrays multidimensionales Arrays multidimensionales. Ejemplo: b[0 : 1][1 : 3] = ((16, 17, 18), (24, 25, 26)) b[1] = (24, 25, 26) b[1][2] = b[1, 2] = 25 Ampliamos la notación para varios índices: (b; [0][3] : 77) = ((16, 17, 77), (24, 25, 26)) (b; [0] : (1, 2, 3)) = ((1, 2, 3), (24, 25, 26)) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 58 / 145 Arrays multidimensionales Definición (Selector) Un selector σ es una secuencia de índices [i1 ][i2 ] . . . [in ] con n ≥ 0. Si n = 0, σ es el selector nulo, denotado como ε. Definición Definimos (b; σ : e) como: (b; ε : e) = e (b[j]; σ : e) si i = j (b; [i]σ : e)[j] = b[j] si i 6= j Ejemplo: dado b[0 : 1][0 : 2][0 : 1] con valor (((0, 1), (10, 11), (20, 21)), ((30, 31), (40, 41), (50, 51))) calcula (b; [0][1][1] : 80)[0][1][0] (b; [0][1][1] : 80)[0][1][1] Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 59 / 145 Arrays multidimensionales Más sencillo: en general, si tenemos (b; [i][j][k ] : α)[r ][s][t] = β podemos desarrollarlo como la disyunción: r =i ∧s =j ∧t =k ∧α=β ∨ (r 6= i ∨ s 6= j ∨ t 6= k ) ∧ b[r ][s][t] = β Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 60 / 145 Guarded Command Language Podríamos usar Pascal o C, pero usamos Guarded Command Language [Dijkstra76] por: 1 2 3 Sintaxis simple y muy reducida Más cómodo para demostración formal Asignaciones simultáneas, no-determinismo Semántica operacional: la usaremos para describir el funcionamiento de cada instrucción. Para cada instrucción, definiremos una relación hestado, instruccióni 7→ estado Ejemplo: h{(x, 1), (y , 2)}, “x := 0”i 7→ {(x, 0), (y , 2)} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 61 / 145 Sintaxis Definición (Instrucción) Una instrucción es una de las siguientes estructuras: 1 skip 2 abort 3 x1 , . . . , xn := α1 , . . . , αn 4 S1 ; S2 5 if B1 → S1 | . . . |Bm → Sm fi 6 do B1 → S1 | . . . |Bm → Sm od donde m ≥ 0, xi son variables (o referencias a arrays), αi son expresiones, Bi son fórmulas (sin cuantificadores) y Si son a su vez instrucciones. Se denominan atómicas a los tres primeros tipos de instrucción, y no atómicas a los tres últimos. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 62 / 145 Semántica operacional Para las instrucciones atómicas: hs, “skip”i 7→ s hs, “abort”i 67→ s0 para cualesquiera s y s0 hs, “x := α ”i 7→ (s; x : s(α)) siempre que s(α) ∈ rango(x) Para la secuencia de instrucciones: hs1 , Si 7→ s2 hs2 , S 0 i 7→ s3 hs1 , S; S 0 i 7→ s3 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 63 / 145 Semántica operacional Ejemplos. Dados x, y : integer y s = {(x, 1), (y , 2)}: hs, “y := x − 1”i 7→ {(x, 1), (y , 0)} hs, “x := y ; skip; y := y − 1”i 7→ {(x, 2), (y , 1)} hs, “skip; abort”i 7→ no existe estado sigte. hs, “x := y /0”i 7→ ídem hs, “x := (y < 0)”i 7→ ídem Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 64 / 145 Asignación múltiple Para asignar varias variables: hs, “x1 , . . . , xn := α1 , . . . , αn ”i 7→ (s; x1 : s(α1 ); . . . ; xn : s(αn )) siempre que s(αi ) ∈ rango(xi ). Es decir, todas las αi se evalúan en s y luego se asigna de izquierda a derecha. Ejemplo: x, y : integer y s = {(x, 1), (y , 2)} hs, “x := y ; y := x”i 7→ {(x, 2), (y , 2)} hs, “x, y := y , x”i 7→ {(x, 2), (y , 1)} hs, “x, y , x := y , x, x − 1”i 7→ {(x, 0), (y , 1)} hs, “x, y := 0, y /x”i 7→ {(x, 0), (y , 2)} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 65 / 145 Asignación con arrays Dado σ = [e1 ][e2 ] . . . [en ] donde cada ei son expresiones, definimos su evaluación en s: s(σ) def = [s(e1 )][s(e2 )] . . . [s(en )] La ejecución de xσ := α produce el efecto: hs, “xσ := α ”i 7→ s; x : (s(x); s(σ) : s(α)) siempre que enrangoi (ei , x) y α ∈ rango(x). Tanto α como σ se evalúan en el estado s. Ejemplos: dado b[0 : 2] : integer y s = {(i, 1), (b, (0, 1, 20))} hs, “b[i + 1] := b[b[i]] + 6”i 7→ {(i, 1), (b, (0, 1, 7))} hs, “b[b[i − 1]] := 7”i 7→ {(i, 1), (b, (7, 1, 20))} hs, “b[i + 2] := 7”i 7→ no hay estado sigte. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 66 / 145 Asignación: caso más general La descripción completa final es: hs, “x1 σ1 , . . . , xn σn := α1 , . . . , αn ”i 7→ (s; x1 : (s(x1 ); s(σ1 ) : s(α1 )); . . . ; xn : (s(xn ); s(σn ) : s(αn ))) siempre que todos los selectores estén en dominio y las expresiones en rango. Es decir: 1 2 3 Se evalúan todos los selectores σi en s Se evalúan todas las expresiones αi en s Se asigna de izquierda a derecha Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 67 / 145 Asignación: caso más general Ejemplos: sean i, b[0 : 2], c[0 : 2] : integer y s = {(i, 1), (b, (0, 2, 1)), (c, (20, 21, 22))} Ejecutar en s las asignaciones: b[1], b[2] := b[0], b[1] b[i − 1], b[i + 1] := b[i + 1], b[i − 1] b[i], c[i], b[1] := i − 1, i + 1, 3 b[i − 1], c[b[i + 1]], i := b[i], c[b[i]] + 3, i + 1 Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 68 / 145 Instrucción condicional if - fi Definición Una instrucción condicional tiene la forma: if | | | B1 → S1 B2 → S2 .. . Bn → Sn fi con n ≥ 0. Cada Si es una instrucción cualquiera y se dice que está custodiada por la condición (o custodia) Bi . La abreviatura IF denota toda la instrucción, mientras que BB es abreviatura de B1 ∨ B2 ∨ · · · ∨ Bn . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 69 / 145 Instrucción condicional Semántica operacional de IF ∀i. s(Bi ) 6= U ∃i. s(Bi ) = T y hs, Si i 7→ s0 hs, IF i 7→ s0 En otras palabras: 1 2 3 Si para algún Bi , s(Bi ) = U, aborta. Si no existe algún Bi , s(Bi ) = T aborta. Toma uno cualquiera de los Bi ciertos y ejecuta Si . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 70 / 145 Instrucción condicional Ejemplo: mirar qué sucede al ejecutar if a = 1 → x := 1 | a/b > 0 → x := 2 | a/b < 0 → x := 3 fi en los estados {(a, 1), (b, 0), (x, 0)} {(a, 0), (b, 1), (x, 0)} {(a, 2), (b, 1), (x, 0)} {(a, 1), (b, 1), (x, 0)} Sirve a la vez de “if-then-else” y de “case”. No hay rama “default” ni sentencia “if-then”. La sentencia Pascal if x<0 then x:=abs(x); hay que escribirla como: if x < 0 → x := abs(x) | x ≥ 0 → skip fi ¿ Qué ocurre si tenemos if fi vacío? Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 71 / 145 Instrucción iterativa do - do Definición Una instrucción iterativa tiene la forma: do | | | B1 → S1 B2 → S2 .. . Bn → Sn od con n ≥ 0. Mantenemos la misma terminología que en IF . La abreviatura DO denota toda la instrucción, mientras que de nuevo BB es abreviatura de B1 ∨ B2 ∨ · · · ∨ Bn . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 72 / 145 Instrucción iterativa Semántica operacional de DO ∀i. s(Bi ) = F hs, DO i 7→ s ∀i. s(Bi ) 6= U ∃i. s(Bi ) = T y hs, Si ; DO i 7→ s0 hs, DO i 7→ s0 En otras palabras: 1 2 3 Si para algún Bi , s(Bi ) = U, aborta. Si s(Bi ) = F para todos los Bi , equivale a skip. Toma uno cualquiera de los Bi ciertos y ejecuta Si , repitiendo luego el bucle. ¿Qué ocurre con el do od vacío? Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 73 / 145 Instrucción iterativa En realidad, tener varias ramas no es estrictamente necesario: DO se puede reescribir como do BB → if B1 → S1 | B2 → S2 . | .. | Bn → Sn fi od Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 74 / 145 Instrucción iterativa Ejemplo: ejecutar los programas: do → i := i − 2 → i := i + 2 | i/abs(i) = 1 i/abs(i) = −1 | i= 6 0 cand i/abs(i) = 1 i= 6 0 cand i/abs(i) = −1 od do → i := i − 2 → i := i + 2 od en s = {(i, 6)}, s0 = {(i, 3)}. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 75 / 145 Algunas definiciones Definición (Trayectoria) Es la secuencia de estados generada por la ejecución de un programa (que termina): s0 −→ s1 −→ . . . −→ sn Ejemplo: i, s := 0, 0; do i 6= 3 → s, i := s + b[i], i + 1 od s0 = {(b, (10, 11, 12)), (i, −1), (s, −3)} Ojo: abortar 6= trayectoria finita. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 76 / 145 Algunas definiciones Definición (Estados finales) Dado un programa S y un estado inicial s0 definimos el conjunto de estados finales Finales(S, s0 ) como todos los sn tales que hs0 , Si 7→ sn y el estado ficticio ⊥ si S no termina en alguna de sus ejecuciones. Definición (Equivalencia de programas) Dos programas S y S 0 son equivalentes sii para todo estado inicial s0 , Finales(S, s0 ) = Finales(S 0 , s0 ). Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 77 / 145 Algunas definiciones ¿ Son estos programas equivalentes al anterior? i, s := 3, 0; do i 6= 0 → s, i := s + b[i − 1], i − 1 od i, s := 3, 0; do i 6= 0 → s, i := s + b[i − 1], i − 1 od ; i := 3 i, s := 0, 0; do i 6= 3 → s, i := s + b[i], i + 1 | i = 2 → skip od Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 78 / 145 Algunas definiciones Dado un subconjunto de identificadores X ⊆ ID y un estado s, def definimos s|X = {(x, v ) | x ∈ X , (x, v ) ∈ s}. def Si A es un conjunto de estados A|X = {s|X | s ∈ A}. Definición (Equivalencia relativa) Dos programas S y S 0 son equivalentes respecto a un cjto. de identificadores X sii para todo estado inicial s0 , Finales(S, s0 )|X = Finales(S 0 , s0 )|X . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 79 / 145 Algunas definiciones Supongamos que etiquetamos todas las instrucciones atómicas de un programa. Definición (Traza) Una traza es una secuencia de etiquetas de instrucciones atómicas generada por la ejecución de un programa (que termina). La misma traza puede ser debida a distintas trayectorias. Dos trayectorias distintas para el mismo s0 ⇒ trazas distintas. Definición (Programa determinista) La ejecución de un programa S en un estado inicial s0 es determinista si genera como mucho una única traza. El programa S es determinista si lo es para cualquier estado inicial s0 . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 80 / 145 Funciones y procedimientos Funciones: parámetros resultado z z }| { }| { func f (v1 : t1 ; . . . ; vn : tn ) ret (r : t) .. . Ejemplos: func abs(x : integer ) ret (a : integer ) if x ≤ 0 → a := −x | x ≥ 0 → a := x fi func fact(i : integer ) ret (f : integer ) if i = 0 → f := 1 | i > 0 → f := fact(i − 1) ∗ i fi Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 81 / 145 Funciones y procedimientos Procedimientos: referencia valor z }| { z }| { 0 0 0 proc f (v1 : t1 ; . . . ; vn : tn ; var v1 : t10 ; . . . ; vm : tm ) .. . Ejemplos: proc swap(var i, j : integer ) i, j := j, i proc div (n, d : integer ; var c, r : integer ) c, r := 0, n; do r ≥ d → c, r := c + 1, r − d od Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 82 / 145 Ejercicios Dado un número x, devolver la primera posición i en un array b[0 : n − 1] tal que b[i] ≥ x. Insertar un elemento x en un array b[0 : n − 1] ordenado desde 0 hasta n − 2. Programar el procedimiento div (n, d, c, r ) de modo recursivo. Función recursiva para el máximo común divisor mcd(a, b). Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 83 / 145 Aserciones Definición Dado un programa S y las fórmulas Q y R, definimos {Q} S {R} como un predicado que es cierto cuando, para todo s0 tal que s0 (Q) = T : ⊥ 6∈ Finales(S, s0 ) y sn (R) = T para todo sn ∈ Finales(S, s0 ). En otras palabras, {Q} S {R} significa: Si S arranca en un estado que satisface Q, entonces se garantiza que termina, y lo hace en un estado que satisface R. Q se denomina precondición y R postcondición. Importante: {Q} S {R} es una fórmula. Intentaremos probar que es una tautología. Método: mediante sustituciones se transforma en una fórmula para el estado inicial. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 84 / 145 Especificación formal Definición (Especificación formal) La especificación formal de un problema consiste simplemente en proporcionar las fórmulas Q y R. Ejemplo: {Q : 0 ≤ a ∧ 0 ≤ b} S {R : z = a ∗ b} Problema: S podría ser asignar todo a ceros. En la especificación incluiremos a veces restricciones: a y b son fijas. Para casos más complicados: usamos letras en mayúsculas. Ejemplos: {0 ≤ a ∧ 0 ≤ b ∧ a = A ∧ b = B} S {R : z = a ∗ b ∧ a = A ∧ b = B} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 85 / 145 Especificación formal Un intercambio se puede expresar como: {x = X ∧ y = Y } swap {y = X ∧ x = Y } Que el array finalice ordenado: {N ≥ 0 ∧ b[0 : N] = B} S {R : perm(b, B) ∧ (∀I ∈ [0, N − 1] : b[I] ≤ b[I + 1])} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 86 / 145 Especificación formal M es el máximo valor max(b[0 : N − 1], M): ∀I ∈ [0, N) : M ≥ b[I] ∧ ∃I ∈ [0, N) : M = b[I] p es la posición del máximo valor de b[0 : N − 1]: 0 ≤ p < N ∧ ∀I ∈ [0, N) : b[p] ≥ b[I] p es la 4a posición donde aparece el valor máximo M: 0 ≤ p < N ∧ max(b, b[p]) ∧ N I ∈ [0, p) : b[I] = b[p] = 3 M es el 3er valor más pequeño del array b[0 : N − 1]: ∃I ∈ [0, N) : M = b[I] ∧ N I ∈ [0, N) : b[I] < M = 2 ¿Problema? Números repetidos. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 87 / 145 Anotación de programas Definición (Programa anotado) Un programa se dice que está anotado si todas sus instrucciones (compuestas o atómicas) están flanqueadas por una pre y una postcondición. Ejemplo {x = X ∧ y = Y } t := x; {t = X ∧ x = X ∧ y = Y } x := y ; {t = X ∧ x = Y ∧ y = Y } y := t {y = X ∧ x = Y } Dos aserciones adyacentes {P}{Q} significan P⇒Q Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 88 / 145 Anotación de programas Segundo ejemplo {n > 0} i, s := 0, 0; {P : s = ΣI ∈ [0, i) : b[I] } do i 6= n cand b[i] = 0 → {P ∧ i 6= n cand b[i] = 0} i := i + 1 {P} | i 6= n → {P ∧ i 6= n} i, s := i + 1, s + b[i] {P} od {s = ΣI ∈ [0, n) : b[I] } Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 89 / 145 Precondición más débil wp Definición (Weakest Precondition wp) Dado un programa S y una fórmula R, wp(S, R) son todos los estados s0 , tales que: ⊥ 6∈ Finales(S, s0 ) y sn (R) = T para todo sn ∈ Finales(S, s0 ) Esto es wp(S, R) son los estados iniciales que garantizan la terminación de S y que además, al acabar se cumple R. Ejemplo: wp(“i := i + 1”, i ≤ 1) = {{(i, 0)}, {(i, −1)}, {(i, −2)}, . . . } Es más cómodo utilizar una fórmula: wp(“i := i + 1”, i ≤ 1) = (i ≤ 0) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 90 / 145 Precondición más débil wp La fórmula debe ser la más débil posible. Por ejemplo i ≤ −10 vale como precondición, pero no es la más débil que cumple las cond. de wp: (i ≤ −10 ⇒ i ≤ 0). Ejemplo: supongamos que S es if x ≥y | x <y → z := x → z := y fi wp(S, z = max(x, y )) = T wp(S, z = y ) = x ≤ y wp(S, z = y − 1) = F wp(S, z = y + 1) = (x = y + 1) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 91 / 145 Precondición más débil wp ¿Tiene sentido wp(S, T )? Indica en qué condiciones se garantiza la terminación del programa. Ejemplo: wp(“do T → skip od ”, T ) = F Importante: {Q} S {R} es cierto si y sólo si: EST (Q) ⊆ wp(S, R) Es decir, si wp está en “formato fórmula", exigimos que Q ⇒ wp(S, R) sea una tautología. Cuando esto sucede, decimos que el programa S satisface la corrección total respecto a Q y R. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 92 / 145 Corrección parcial Definición (Corrección parcial) El predicado Q{S}R denota la corrección parcial de S respecto a Q y R y equivale a afirmar: para todo s0 y para todo sn ∈ Finales(S, sn ), sn 6= ⊥, se cumple sn (R) = T . En otras palabras: Si iniciamos S en un estado que satisface Q, y se da que termina, entonces satisface R al acabar. No garantiza la terminación de S ¡se cumple trivialmente cuando S no termina! Ejemplo: T {do T → skip od }T es una tautología. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 93 / 145 Propiedades de wp Propiedades: 1 wp(S, F ) = F 2 wp(S, α) ∧ wp(S, β) = wp(S, α ∧ β) 3 Si α ⇒ β entonces wp(S, α) ⇒ wp(S, β) 4 wp(S, α) ∨ wp(S, β) ⇒ wp(S, α ∨ β) 5 wp(S, α) ∨ wp(S, β) ⇐ wp(S, α ∨ β), si S es determinista. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 94 / 145 Semántica axiomática Caracterizar las instrucciones mediante su wp (semántica axiomática) wp(“skip”, R) = R wp(“abort”, R) = F wp(“S1; S2”, R) = wp(S1, wp(S2, R)) Ejemplos: wp(“skip; skip”, R) = R wp(“S1; (S2; S3)”, R) = wp(“(S1; S2); S3”, R) wp(“S; abort”, R) = F Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 95 / 145 Asignación Asignación “x := e". El identificador x toma el valor de la expresión e. wp(“x := e”, R) = dominio(e) cand Rex donde dominio(e) es una expresión que cubre todos los s tal que s(e) 6= U. Habitualmente, dominio(e) = T . Ejemplos: wp(“x := 5”, x = 5) = T wp(“x := 5”, x 6= 5) = F wp(“x := x + 1”, x = 5) = (x = 4) wp(“x := x + 1”, x < 0) = (x < −1) wp(“x := a/b”, x 6= 1) = (b 6= 0) cand a/b 6= 1 wp(“x := b[i]”, x = b[i]) = dominio(i, b) cand T Recordar: si s(i) está fuera de rango, s(b[i]) = U Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 96 / 145 Asignación ¿ Es x := e determinista? Ausencia de efectos colaterales: dados x e y distintos y dada la constante C, wp(“x := e”, y = C) = (y = C) Cuando tenemos una secuencia de instrucciones: wp(“S1; S2; S3; S4”, R) = wp(“S1; S2; S3”, wp(“S4”, R)) = wp(“S1; S2”, wp(“S3”, wp(“S4”, R))) = wp(“S1”, wp(“S2”, wp(“S3”, wp(“S4”, R)))) vamos calculando hacia atrás: {wp1 } S1 {wp2 } S2 {wp3 } S3 {wp4 } S4 {R} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 97 / 145 Asignación La asignación x1 , . . . , xn := e1 , . . . , en , o simplemente x := e, donde las xi son distintas, se define: wp(“x := e”, R) = dominio(e) cand Rex Ejemplos: wp “s, i := s + b[i], i + 1”, i > 0 ∧ s = ΣJ ∈ [0, i) : b[J] wp(“x, y := x/y , y /x”, x ∗ y = 0) Encontrar un contraejemplo de wp(“x, y := e1 , e2 ”, R) = wp(“x := e1 ; y := e2 ”, R) wp(“x, y := e1 , e2 ”, R) = wp(“y := e2 ; x := e1 ”, R) ¿ Cuándo se pueden garantizar estas igualdades? Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 98 / 145 Asignación Interesante: también se puede usar wp para escribir el programa. Ejemplo: Queremos i := m + 1 pero que n siga indicando el número de elementos. i ... m m+1 ... i+n ... ... n elementos m ... ... i i+n ... ... n elementos Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 99 / 145 Asignación El programa tendrá el aspecto: {i + n = C} i, n := m + 1, α {i + n = C} donde α es lo que queremos calcular wp(S, i + p = C) = (m + 1 + α = C) Cuidado si las variables cambian: {T } a := a + 1; b := α {a = b} wp(S, a = b) = (a + 1 = α) pero esa ‘a’ es en el estado inicial. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 100 / 145 Asignación Un par de ejemplos más: 1 {T } i := i + 1; j := α; j := j ∗ 2 {j = i} Solución: α = (i/2) 2 {a = A ∧ b = B ∧ c = C} a := a − b; b := α; c := b − a {c = 2 ∗ A} Solución: α = 2 ∗ (a + b) + a Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 101 / 145 Asignación Arrays: se usa la interpretación como función: wp(“b[i] := e”, R) = wp(“b := (b; i : e)”, R) b = dominio((b; i : e)) cand R(b;i:e) = enrango(i, b) cand dominio(e) b cand R(b;i:e) Ejemplos: wp(“b[i] := 5”, b[i] = 5) wp(“b[i] := 5”, b[i] = b[j]) wp(“b[b[i]] := i”, b[i] = i) wp(“b[n] := x”, ordenado(b[1 : n])) Ejemplo interesante: wp(“b[i] := 3; b[j] := 5”, b[i] = 3) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 102 / 145 Inciso: ejercicios Solución a: M es el tercer valor más pequeño del array b[0 : n − 1] : integer ∃I ∈ [0, n) : b[I] = M ∧ N I ∈ [0, n) : b[I] < M ∧ ¬ ∃J ∈ [0, I) : b[J] = b[I] = 2 Nuevo acertijo: tenemos este fragmento de un programa Pascal x:=3; y:=5; writeln(x); pero el writeln muestra un 5. ¿ Cómo es posible? Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 103 / 145 Asignación Asignación general: x1 σ1 , . . . , xn σn := e1 , . . . , en xσ := e Definimos: wp(“xσ := e”, R) def = Rexσ Problema: hay que redefinir la sustitución textual. (xσ) no son identificadores. Para ello: 1 2 reagrupar todas las referencias al mismo array, respetando el orden, aplicar sustitución de arrays. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 104 / 145 Asignación Ejemplos: b[i],c[2][4],b[2],c[i][0] R1,2,3,4 b[i],b[2],c[2][4],c[i][0] = R1,3,2,4 b,c = R(b;i:1;2:3),(c;[2][4]:2;[i][0]:4) x,x R1,2 x = R(x;ε:1;ε:2) = R2x Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 105 / 145 Ejemplos 1 2 wp(“b[i], b[j] := b[j], b[i]00 , b[i] = X ∧ b[j] = Y ) wp(“b[i], b[j] := b[j], b[i]00 , R) con R : ∀K ∈ [0, n) ∧ K 6= i ∧ K 6= j : b[K ] = B[K ] 3 wp(“i, b[i] := i + 1, 000 , 0 < i ∧ ∀J ∈ [0, i) : b[J] = 0 ) 4 wp(“p, b[p], b[b[p]] := b[p], b[b[p]], p00 , p = b[b[p]]) 5 wp(“b[0], b[1] := b[1], b[0]00 , b[0] = b[b[1]]) 6 wp(“b[i], b[j] := 1, 200 , b[i] = b[j]) 7 wp(“b[b[i]] := b[i]00 , b[b[j]] = j) 8 Se ha detectado que la asignación b[b[i]] := b[j] a veces no cumple la postcondición b[b[i]] = b[j]. Explicar cómo es posible. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 106 / 145 Instrucción condicional El wp de un IF se define como: wp(IF , R) = dominio(BB) ∧ BB ∧ ∧(B1 ⇒ wp(S1 , R)) ∧ . . . ∧(Bn ⇒ wp(Sn , R)) Probar Q ⇒ wp(IF , R) equivale a probar: i) Q ⇒ dominio(BB) ii) Q ⇒ BB iii) Q ∧ Bi ⇒ wp(Si , R) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 107 / 145 Ejemplo Dado el array b[0 : m − 1] : integer , calcular wp(IF , R) donde: IF : if b[i] > 0 → i, p := i + 1, p + 1 | b[i] < 0 → i := i + 1 fi {R : i ≤ m ∧ p = N J ∈ [0, i) : b[J] > 0 } Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 108 / 145 Más ejemplos Demostrar que wp(IF , abs(x) = z) es T , donde: IF : if x ≥ 0 → z := x | x ≤ 0 → z := −x fi wp(“if fi 00 , T ) wp(“if x = 0 → z := x + 1 | x = 0 → z := 2 ∗ x + 1 fi 00 , z = 1) Búsqueda binaria: {Q : ordenado(b[0 : n − 1]) ∧ 0 ≤ i < k < j < n ∧ x ∈ b[i : j]} IF : if b[k ] ≤ x → i := k | b[k ] ≥ x → j := k fi {R : x ∈ b[i : j]} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 109 / 145 Más ejemplos Cociente y resto {T } if d ≤ r → r , c := r − d, c + 1 | d > r → skip fi {c ∗ d + r = n ∧ r ≥ 0} wp(“if a = 0 → skip fi 00 , T ) Calcula el wp para if a > b → a := a − b | b > a → b := b − a fi {a > 0 ∧ b > 0} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 110 / 145 Instrucción iterativa Precondición más débil de un DO sabiendo el número k de iteraciones wpk (DO , R). Ejemplo con k = 3 iteraciones: {wp3 (DO , R) ? } do B1 → S1 | B2 → S2 od {R} Equivale a: if B1 → S1 | B2 → S2 fi ; if B1 → S1 | B2 → S2 fi ; if B1 → S1 | B2 → S2 fi {R} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 111 / 145 Instrucción iterativa Precondición más débil de un DO : i) Para acabar en 0 iteraciones: wp0 (DO , R) = ¬BB ∧ R ii) Para acabar en k > 0 iteraciones: wpk (DO , R) = wp(IF , wpk −1 (DO , R)) iii) Para acabar en cualquier número de iteraciones: wp(DO , R) = (∃K : 0 ≤ K : wpK (DO , R))) Problema: no aplicable en la práctica. El desarrollo de wp(DO , R) es recursivo y puede ser que nunca terminemos de elaborarlo. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 112 / 145 Instrucción iterativa Utilizaremos la siguiente técnica: 1 2 3 Para demostrar corrección parcial: buscaremos una fórmula, llamada invariante, cierta antes y después de toda iteración del bucle (incluso al terminar). Para demostrar que el bucle finaliza: buscaremos una función t, llamada función cota, que en cada iteración sea positiva y decreciente. Ejemplo: i, s := 1, b[0]; do i < 11 → i, s := i + 1, s +b[i] od {R : s = ΣK ∈ [0, 11) : b[K ] } Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 113 / 145 Instrucción iterativa Normalmente escribiremos: {Q : . . .} hinicialización del buclei {inv P : . . .} {cota t : . . .} do B1 → S1 | . . . |Bn → Sn od {R : . . .} Método de prueba: demostrar los cinco puntos: 1 2 3 4 5 P cierto justo antes de empezar el bucle, {P ∧ Bi }Si {P} para cada rama, P ∧ ¬BB ⇒ R, (hasta aquí: corrección parcial) P ∧ BB ⇒ (t > 0), {P ∧ Bi }t1 := t; Si {t < t1} para cada rama. (ahora: corrección total) Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 114 / 145 Instrucción iterativa Otro ejemplo: {b ≥ 0} x, y , z := a, b, 0; {P : y ≥ 0 ∧ z + x ∗ y = a ∗ b} {t : y } do y > 0 ∧ par (y ) → y , x := y /2, x + x | ¬par (y ) → y , z := y − 1, z + x od {R : z = a ∗ b} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 115 / 145 Instrucción iterativa: más ejemplos 1 Encontrar x en un array {n ≥ 0} i := 0; {P : 0 ≤ i ≤ n ∧ x 6∈ b[0 : i − 1]} {t : n − i} do i < n cand x 6= b[i] → i := i + 1od {R : (i = n ∧ x 6∈ b[0 : n − 1]) ∨ (0 ≤ i < n cand x = b[i])} 2 Sumar 1 a todos los elementos de b[0 : n − 1] : integer . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 116 / 145 Instrucción iterativa: más ejemplos Fibonacci: dada la función auxiliar si i = 0 0 def 1 si i = 1 fi = fi−1 + fi−2 si i > 1 demostrar {n > 0} i, a, b := 1, 1, 0; {P : 1 ≤ i ≤ n ∧ a = fi ∧ b = fi−1 } {t : n − i} do i < n → i, a, b := i + 1, a + b, a od {R : a = fn } Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 117 / 145 Instrucción iterativa: más ejemplos Ejemplo más grande: {Q : n > 0} i := 1; k := 0; {P : 0 < i ≤ n ∧ 0 ≤ k < n ∧ b[k ] ≥ b[0 : i − 1]} {t : n − i} do i < n → {P ∧ i < n} if b[i] ≤ b[k ] → skip | b[i] ≥ b[k ] → k := i fi ; i := i + 1; {P} od {P ∧ ¬(i < n)} {R : 0 ≤ k < n ∧ b[k ] ≥ b[0 : n − 1]} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 118 / 145 Derivación de programas Idea: usar la prueba como guía para programar. Ejemplo: encontrar S tal que: {T } S {R : z = max(x, y )} o, lo que es lo mismo: R = (z ≥ x ∧ z ≥ y ∧ (z = x ∨ z = y )) La programación es una tarea orientada dirigida por el objetivo. Importante: hacer bien la especificación. Sobre todo R y, en menor medida, Q. Veremos posibles estrategias para desarrollar el programa a partir de la especificación. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 119 / 145 Estrategias par el IF Estrategia 1. Para construir un IF : 1 2 3 Identificar una instrucción S que haga cierto R en algún(os) caso(s). Encontrar una condición B t.q. B ⇒ wp(S, R) y crear una rama del IF con B → S. Si la precondición Q no implica la disyunción de todas las ramas, volver al paso 1. Otro ejemplo: encontrar un programa que devuelva en x e y resp. el mínimo y el máximo de los valores originales de x e y . Principio general: hacer las condiciones custodia tan fuertes como sea posible. Ejemplo: j debe contener el resto de k /10 en todo momento. Queremos incrementar k y que j se actualice adecuadamente. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 120 / 145 Estrategias par el DO Estrategia 2 para construir un DO a partir de P y t: 1 Identificar una condición B tal que P ∧ ¬B ⇒ R. 2 Desarrollar el cuerpo del bucle de modo que: F la cota t disminuya, F la invariante P se mantenga cierta. Principio general: hacer la custodia B tan débil como sea posible. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 121 / 145 Estrategias par el DO Ejemplo: {R : s = ΣJ ∈ [0, n) : b[J] } {P : 0 ≤ i ≤ n ∧ s = ΣJ ∈ [0, i) : b[J] } {t : n − i} Ejemplo: buscar x en b[0 : m − 1, 0 : n − 1] {Q : b[0 : m − 1, 0 : n − 1] : integer ∧ m > 0 ∧ n > 0} {R : (i = m ∧ x 6∈ b) cor (0 ≤ i < m ∧ 0 ≤ j < n ∧ x = b[i, j])} {P : 0 ≤ i ≤ m ∧ 0 ≤ j < n ∧ NoEsta(i, j)} {t : n ∗ (m − i) − j} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 122 / 145 Estrategias par el DO Estrategia 3 para inicializar el bucle, buscar una instrucción que haga P trivialmente cierto o deducible a partir de Q. Ejemplo: cuantificadores → buscar rango vacío. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 123 / 145 Estrategias par el DO Estrategia 4 para construir un DO a partir de P y t: 1 Identificar casos Bi → Si que decrementan t manteniendo P. 2 Cuando P ∧ ¬BB ⇒ R, parar. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 124 / 145 Estrategias par el DO Ejemplo: 4-swap {Q : y0 = Y0 ∧ y1 = Y1 ∧ y2 = Y2 ∧ y3 = Y3 } {R : y0 ≤ y1 ≤ y2 ≤ y3 ∧ perm(y , Y )} {P : perm(y , Y )} {t : nmerodedesrdenes N I, J : 0 ≤ I < J < 4 : yI > yJ } Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 125 / 145 Estrategias par el DO Ejemplo: buscar x en b[0 : m − 1, 0 : n − 1] 2a versión {Q : b[0 : m − 1, 0 : n − 1] : integer ∧ m≥0 ∧ n≥0} {R : (i = m ∧ x 6∈ b) cor (0 ≤ i < m ∧ 0 ≤ j < n ∧ x = b[i, j])} {P : 0 ≤ i ≤ m ∧ 0 ≤ j≤n ∧ NoEsta(i, j)} {t : (m − i) ∗ n − j + m − i} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 126 / 145 Teoría del globo INI= estados iniciales (antes del bucle), R=poscondición. P debe ser cierta antes y después: P INI R La ejecución “desinfla” P hasta llegar a R: P INI P1 P2 P3 R Para obtener P: “inflar” o “debilitar” R. En cada iteración tendremos: Pi = P ∧ 0 ≤ t ≤ ti . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 127 / 145 Reducir una conjunción Reducir algo como A ∧ B ∧ C a A ∧ C. Estrategia 5. Al borrar un fragmento B de una conjunción en R para derivar P, usar la negación de ese fragmento como custodia B del bucle. Ejemplo: Aproximar la raíz cuadrada de n. Estrategia 6. Para encotrar un valor mínimo (resp. máximo) que satisface una propiedad, comenzar por la cota inferior (resp. superior) e ir incrementando (resp. decrementando). Ejemplo: búsqueda lineal. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 128 / 145 Cambio de constante por variable Estrategia 7. Cambiar un valor constante de R por un nuevo identificador. Fijar el rango del identificador: al acabar, debe ser igual a la constante. Ejemplos: I I I Suma de elementos de un array. Aproximar la raíz cuadrada de n. Buscar la mayor meseta. Principio. Introducir una variable sólo si es necesario. Ej: 1 2 debilitar R, cambiando constante por nueva variable optimizar un cálculo local Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 129 / 145 Expresar parte no modificada Estrategia 8. Si es importante que la parte no modificada del problema esté como en la situación inicial Q, incluirlo en P. Si se modifica un array, casi siempre hará falta. Ejemplos donde hace falta: I I Insertar espacios Shift right circular. Ejemplo donde no es necesario: I Colocar en b[n − 1] el máximo del array b[0 : n − 1] : integer . Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 130 / 145 Evitar posiciones aisladas Estrategia 9. Evitar referirse a posiciones aisladas en P sustituyéndolas, siempre que sea posible, por intervalos de posiciones. Ejemplo: dados b[0 : n − 1], c[0 : m − 1] : integer con m, n ≥ 0 ordenados crecientemente y sin repetidos, obtener en p el número de elementos comunes a ambos. b[i] > b[0 : i − 1] es no definido cuando i = n. Pero podemos cambiarlo por b[i : n − 1] > b[0 : i − 1] y con i = n tendríamos ∀ con rango vacío. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 131 / 145 Usar constantes auxiliares Estrategia 10. Nombrar con una constante auxiliar c el valor final que se desea para una variable i. Luego usar i = c en R y aumentar el rango de i en P, p. ej., 0 ≤ i ≤ c. Cuidado: c es como una función o predicado auxiliar. Podemos usarla en las aserciones pero no en el programa. Ejemplos: 1 2 Búsqueda lineal Welfare crook Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 132 / 145 Funciones cota La función cota sirve para: 1 2 Probar que el bucle termina Proporcionar una cota superior del número de iteraciones. Ejemplo: programas para 1 2 √ n √ programa a := a + 1, cota t : ceil( n) − a programa d := (a + b)/2, cota t : b − a + 1, pero también t : ceil(log(b − a)) Estrategia 11. Identificar la parte no resuelta del problema y buscar una expresión matemática que permita medirla. Ejemplo: buscar en un array bidimensional. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 133 / 145 Funciones cota Estrategia 12. Detectar orden lexicográfico en tuplas de números o de índices (especialmente para arrays). (a0 , a2 , . . . , an−1 ) < (b0 , b2 , . . . , bn−1 ) se define como: ∃I ∈ [0, n) : ∀J ∈ [0, I) : aJ = bJ ∧ aI < bI Sea una tupla ~a = (a0 , . . . , an−1 ) de expresiones con variables usadas en un bucle. Supongamos que cada ai se mueve en mi ≤ ai ≤ Mi y que ~a decrece lexicográficamente. Entonces: 1 2 el bucle termina, y una cota válida es t = ΣI ∈ [0, n) : (aI − mI ) ∗ ΠJ ∈ [I + 1, n) : MJ − mJ + 1 Ejemplos: array bidimensional, ordenar una 4-tupla, problema de los trenes. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 134 / 145 Funciones Las definiciones tienen la forma: func f (X ) ret r {Q} S {R} Por simplicidad, supondremos que: I I I En Q sólo aparecen libres las X . En R sólo aparecen libres las X y r . Las variables internas de f no se usan en el resto del programa. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 135 / 145 Funciones Ejemplo: func abs(X ) ret r {Q : T } if X ≥ 0 → r := X | X ≤ 0 → r := −X fi {R : X ≥ 0 ∧ r = X ∨ X ≤ 0 ∧ r = −X } Las llamadas tienen la forma y σ := α f (e) I I I I donde: e son expresiones del mismo tipo que X . y σ coincide en tipo con m. α f (e) es una expresión que contiene a f (e) una sola vez. f no aparece en σ ni en e. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 136 / 145 Funciones Algunas llamadas posibles serían: y := abs(10 − a ∗ 2); b[0] := abs(b[1] − b[2]); y := abs(a) + 1 pero descartamos llamadas del estilo: z := abs(abs(a) − z); b[abs(i − j)] := 0 que pueden ser sustituidas por asignaciones intermedias: aux0 := abs(a); z := abs(aux0 − z); aux1 := abs(i − j); b[aux1] := 0; Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 137 / 145 Funciones La llamada y := f (e) equivale a ejecutar: X := e; S; y := α(r ) Supongamos que hemos demostrado {Q} S {R}. Para demostrar: {G} y := α f (e) {H} debemos realizar los siguientes pasos: 1 2 G ⇒ QeX y G ∧ ReX ⇒ Hα(r ) Ejemplo: demostrar {a > b ∧ c > 0} b := c ∗ abs(a − b) {b > 0} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 138 / 145 Procedimientos Las definiciones tienen la forma: proc p(X ; var r ) {Q} S {R} De nuevo, suponemos que: I I I En Q sólo aparecen libres las X . En R sólo aparecen libres las X y r . Las variables internas de p no se usan en el resto del programa. y además: I Las variables r funcionan por “copia local”. Esto es, la llamada p(e, y ) equivale a: X , r := e, y ; S; y := r Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 139 / 145 Procedimientos Ejemplo: proc incr (X ; var r ) {Q : r = Z } r := r + X ; {R : r = Z + X } I I Supongamos que hemos demostrado {Q} S {R}. Para demostrar: {G} y := f (e) {H} debemos realizar los siguientes pasos: 1 X ,r G ⇒ Qe,y 2 G ∧ ReX ⇒ Hry Ejemplo: demostrar {a ≥ 0 ∧ b = B} incr (a + 1, b) {b > B} Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 140 / 145 Recursividad Definición La función (o procedimiento) f es recursiva si su ejecución puede producir una nueva llamada a f . Ejemplo: func fact(X ) ret r if X = 0 → r := X | X > 0 → r := X ∗ fact(X − 1) fi Recursividad directa: la llamada a f se produce en el cuerpo de f . Ejemplo: fact. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 141 / 145 Recursividad Recursividad indirecta: f llama a otra función g cuya ejecución acaba finalmente llamando a f de vuelta. Ejemplo: func par (X ) ret r : boolean if X = 0 → r := T | X > 0 → r := impar (X − 1) fi func impar (X ) ret r : boolean if X = 0 → r := F | X > 0 → r := par (X − 1) fi Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 142 / 145 Recursividad Dentro de recursividad directa . . . simple o lineal: cada ejecución del cuerpo de f genera como mucho una nueva llamada a f (a primer nivel). Ejemplo: fact. múltiple o no lineal: ejecutar el cuerpo de f puede suponer hacer uso de f dos o más veces. Ejemplo: func fibo(X ) ret r if X = 0 → r := 0 | X = 1 → r := 1 | X > 1 → a := fibo(X − 1); b := fibo(X − 2); r := a + b fi Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 143 / 145 Recursividad Dentro de recursividad directa lineal . . . final (tail): la llamada es la última instrucción ejecutada. Ejemplo: fact. Ejemplo de no final: func max(B[0 : N − 1], I, D) ret r if I<D → r := max(B, I + 1, D) | I=D → r := B[I] fi ; if B[I] > r → r := B[I] | B[I] <= r → skip fi Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 144 / 145 Recursividad Para probar la corrección: igual que una llamada a función normal salvo: 1 Cuidado con los nombres de variables. Truco: usar f (X ) para la función que llama y f 0 (X 0 ) para la llamada. 2 Hace falta demostrar terminación. Usamos una cota t: F F Probar Q ⇒ t > 0 Probar que el valor de t antes de una nueva llamada es estrictamente mayor que su valor justo después de pasar los parámetros a la nueva llamada. Pedro Cabalar ( Depto. de Computación Universidade da Coruña TP,[email protected] ETIX ) curso 2009/2010 145 / 145