Introducción - Departamento de Computación
Transcripción
Introducción - Departamento de Computación
1 Introducción Antony Hoare: 1962 Quicksort 1969 Programación estructurada. Lógica de Hoare (semántica axiomática") Objetivo: demostrar lógicamente la corrección de un programa. Método: usando fórmulas lógicas expresamos • Precondición: requerida antes de ejecutar • Postcondición: garantizada después de ejecutar Necesario: dotar de semántica al lenguaje de progra- mación. Universidade da Coruña Departamento de Computación 2 Un ejemplo simple Calcular el resto r y el cociente c de x/y ... r:=x; c:=0; while r>y do begin r:=r-y; c:=c+1; end; ... Opciones para depurar errores: ⇒ 1. Meter write's" 2. Interrupción selectiva Universidade da Coruña demasiada salida Departamento de Computación 3 ... {y>0} r:=x; c:=0; while r>y do begin r:=r-y; c:=c+1; end; {x=y*c+r} ... Problema: x=6, y=3, c=1, r=3. Debería ser r<y Cambiamos la postcondición: {x=y*c+r and r<y} La condición del bucle no garantiza r<y al acabar: while r>=y do Nuevo problema: obtenemos un r=-2 con x=-2 Cambiar precondición: {y>0 and x>=0} Universidade da Coruña Departamento de Computación 4 Ejercicio Cálculo del máximo común divisor (MCD) 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? Universidade da Coruña Departamento de Computación 5 Tema 1. Cálculo Proposicional SINTAXIS Partimos de un conjunto de (ejemplo: identicadores, ID ID = {x, y, r, c}) Denición (fórmula proposicional) Cualquiera de las expresiones: i) T v) α∨β ii) F vi) α∧β iii) p vii) α⇒β iv) ¬α viii) α=β donde p identicador y Precedencia: ix) α, β (α) fórmulas prop. ‘¬' < ‘ ∧ ' < ‘ ∨ ' < ‘ ⇒ ' < ‘ = ' (los binarios son de izquierda a derecha) Universidade da Coruña Departamento de Computación 6 Tema 1. Cálculo Proposicional SEMÁNTICA Denición (estado) Un estado s es una función del tipo: s : ID −→ {T, F } también representable como cjto. de pares Ejemplo: si entonces s = {(x, T ), (y, F ), (r, F ), (c, T )} s(x) = T, s(y) = F, Def. Una fórmula proposicional en el estado (id, valor). etc. α está bien denida s sii para todo identicador p en α, existe (p, v) ∈ s. Universidade da Coruña Departamento de Computación 7 Ampliamos el uso de s(·) a cualquier fórmula propo- sicional. Def. (función Si de evaluación) α bien denida en s, entonces s(α) se obtiene reemp en α por s(p) y aplicando las tablas: plazando todo 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 Def. (tautología) Cualquier fórmula bien denida, Ejemplos: Universidade da Coruña α tal que, para todo s en que esté s(α) = T . T , p ∨ ¬p, b ∧ c ∧ d ⇒ (d ⇒ b) Departamento de Computación 8 Tema 1. Cálculo Proposicional Probar que α es tautología = probar todos los esta- dos. Probar que no lo es = encontrar un contraejemplo Una alternativa interesante: una fórmula proposicional α 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 identicaremos α con EST (α) y vicever- sa. A partir de un conjunto de estados: ¾ Cómo obtener la fórmula que los representa? Universidade da Coruña Departamento de Computación 9 Def. (fórmula más débil/más fuerte) Si α⇒β si EST (α) ⊆ EST (β), α es más fuerte que es un tautología, es decir, β entonces (o β más débil que α). ¾ Cuáles son las fórmulas más fuerte y más débil posibles? Universidade da Coruña Departamento de Computación 10 Tema 1. Cálculo Proposicional Regla de Si sustitución uniforme α = β 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 α=β lo es y β=γ son tautologías, entonces también α = γ. Ejemplo: probar (α ⇒ β) = (¬β ⇒ ¬α) Ejemplo: probar la regla de contradicción (21) a partir de las restantes. Universidade da Coruña Departamento de Computación 10 Tema 1. Cálculo Proposicional Del lenguaje natural al formal... A ⇒ B A implica B A es suciente para B B es necesario para A si A entonces 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 ≡ B A equivale a A B A si y sólo si A ó B (inclusivo) A 6≡ B A ó B (exclusivo) A∨B Universidade da Coruña B B Departamento de Computación 11 Tema 1. Cálculo Proposicional Otro método: Tablas semánticas Reglas de transformación: Fórmula Rama 1 Rama 2 α∨β α α∧β α, β ¬(α ∨ β) ¬α, ¬β ¬(α ∧ β) ¬α ¬β α⇒β ¬α β β ¬(α ⇒ β) α, ¬β α=β α, β ¬(α = β) α, ¬β ¬¬α Universidade da Coruña ¬α, ¬β ¬α, β α Departamento de Computación 12 Tema 1. Cálculo Proposicional Tablas semánticas Cada línea de transformación corresponde a una equivalencia. Ejemplo: Fórmula Rama 1 Rama 2 α⇒β ¬α β corresponde a: α ⇒ β = ¬α ∨ β La fórmula nal es la Forma Normal Disyuntiva (FND). Los literales de cada rama constituyen una cláusula. Una rama abierta corresponde a un contraejemplo. Universidade da Coruña Departamento de Computación 13 Tema 2. Predicados: SINTAXIS Por el momento, permitimos expresiones relacionales en el lugar de identicadores. Ejemplo: a ≥ b ∨ ¬(c < d) Operaciones relacionales y aritméticas predenidas: ≤, ≥, <, >, =, 6=, +, −, ∗, / Precedencia: la habitual. Todos mayor prioridad que los lógicos. Usando terminología lógica estándar: ≤, ≥, >, <, =, 6= son predicados binarios funciones binarias +, −, ∗, / son − función unaria es una 0, 1, 2, −1, −2, T, F Universidade da Coruña son nombres de constantes Departamento de Computación 14 Tema 2. Predicados: SEMÁNTICA Tenemos un conjunto de valores constantes: V alores = {0, 1, 2, −1, −2, T, F, ...} Denimos tipos. de valores rango(i). Cada identicador i tiene un rango Ejemplos: def i : boolean = rango(i) = {T, F } def i : natural = rango(i) = {0, 1, 2, . . . } def i : integer = rango(i) = {. . . , −2, −1, 0, 1, 2, . . . } Def. (estado) Un estado, s, es una función del tipo: s : ID −→ V alores también representable como cjto. de pares modo que Universidade da Coruña (i, v), de v ∈ rango(i). Departamento de Computación 15 Tema 2. Predicados: SEMÁNTICA Ejemplo: rango(x) = {0, 1, 2} y : integer b : boolean s = {(x, 0), (y, −3), (b, F )} Igual que en proposicional, ampliamos el uso de s(·) a cualquier fórmula de predicados. Def. (función Si de evaluación) α bien denida en s, entonces s(α) se obtiene reem- plazando todo x en α raciones predenidas Universidade da Coruña por s(x) y aplicando las ope- ≤, ≥, <, >, +, ∗, etc. Departamento de Computación 16 Tema 2. Predicados: SEMÁNTICA Como ayuda, pensar en la tabla: + · · · −2 −1 0 1 2 · · · .. . .. . .. . .. . .. . .. . .. . .. . −1 · · · −3 −2 −1 0 1 · · · 0 · · · −2 −1 0 1 2 · · · 1 · · · −1 0 1 2 3 ··· .. . .. . .. . .. . .. . k1 − k2 es un k1 ∗ k2 es sumar k3 .. . tal que k1 .. . .. . k3 + k2 da k1. Ejemplo: 1 − 2 veces el valor k2 , ajustando el ∗ signo. Ejemplo: construir la tabla para ` '. −k es k1/k2 (−1) ∗ k . es un Universidade da Coruña k3 tal que k3 ∗ k2 da k1. Ejemplo: 2/ − 1 Departamento de Computación 17 Tema 2. Predicados: SEMÁNTICA Las relaciones de orden se pueden denir a partir de = · · · −2 −1 0 1 2 · · · .. . .. . .. . .. . .. . .. . .. . .. . −1 · · · F T F F F ··· 0 ··· F F T F F ··· 1 ··· F F F T F ··· .. . .. . .. . .. . .. . .. . .. . .. . y: ≤ · · · −2 −1 0 1 2 · · · .. . .. . .. . .. . −1 · · · F T .. . .. . .. . .. . T T T ··· 0 ··· F F T T T ··· 1 ··· F F F T T ··· .. . .. . .. . .. . .. . .. . .. . .. . Pensar en cómo denirlos para el caso booleano. Universidade da Coruña Departamento de Computación 18 Tema 2. 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 ¾ quién es F pero: −3/0? Introducimos un nuevo valor: Para cualquier U ( undened"). k , s(k/0) = U En todas las tablas de operadores vistas, si al menos un operando es U, bién. Ejemplos: s(−U ) = U, s(3 ∗ U ) = U, s(F ∨ entonces el resultado es U tam- U ) = U, s(¬U ) = U Ejemplo: Universidade da Coruña s( x/0 = y/0 ) Departamento de Computación 19 2.1. Nuevos operadores α β α α α α cor si α cor β α≡β F F T F U F U F F T F T F U F U U F U U U U T U T U U F T F F T F T U U T F T T T T T β equivale a: entonces β β, en otro caso F" equivale a: entonces α≡β β α F F cand si cand T, en otro caso β" no lo usaremos dentro del programa. Universidade da Coruña Departamento de Computación 20 2.1. Nuevos operadores Probar que (α cand β≡β cand α) no es tautolo- gía. En cambio, sí lo son las siguientes fórmulas. Asociatividad: α cand α (β cor cand (β cor γ) ≡ (α cand γ) ≡ (α cor β) β) cor (α cand cand (α cor β) cand cor γ γ Distributividad: α cand α cor cor γ) ≡ (α cand cand γ) ≡ (α cor (β (β β) γ) γ) De Morgan: ¬(α cand ¬(α Universidade da Coruña cor β) ≡ ¬α cor ¬β β) ≡ ¬α cand ¬β Departamento de Computación 21 2.1. Nuevos operadores Simplicaciones: α α Si α (α cor cand α cor α ≡ α α cor F ≡ α cand β) ≡ α α cand α ≡ α α cand T ≡ α (α cor β) ≡ α s(α) 6= U ) está bien denida ( cor T ≡ T cand F ≡ F α α cor ¬α ≡ T cand ¬α ≡ F α α Universidade da Coruña entonces: Departamento de Computación 22 2.2. Cuanticadores Consideremos expresiones del estilo: αm ∨ αm+1 ∨ · · · ∨ αn−1 donde αi (1) son fórmulas de predicados que pueden ha- cer referencia al valor constante i. La fórmula (1) se puede abreviar como: (∃i : m ≤ i < n : αi) Ejemplo: la fórmula (∃i : 2 ≤ i < 6 : x = 2 ∗ i) es lo mismo que: x=2∗2∨x=2∗3∨x=2∗4∨x=2∗5 Universidade da Coruña Departamento de Computación 23 2.2. Cuanticadores 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, ni o [m, n − 1]: (∃i ∈ [m, ni : αi) = (∃i : m ≤ i < n : αi) Correspondencia con notación clásica: ∃ i (m ≤ i ∧ i < n ∧ αi) ½ Mucho cuidado !: • Los cuanticadores no son parte del programa. Sólo aparecen en las condiciones entre llaves. • La variable cuanticada no es un identicador del programa. Es como una abreviatura de todos sus valores Universidade da Coruña [m, n − 1]. Departamento de Computación 24 2.2. Cuanticadores Usaremos: MAYÚSCULAS = variables cuanticadas, minúsculas = identicadores del programa. Denición recursiva del ∃: 1. (∃I ∈ [m, mi : αI ) = F 2. (∃I ∈ [m, k + 1i : αI ) = (∃I ∈ [m, ki : αI ) ∨ αk , para k ≥ m. Caso 1: con rango vacío equivale a falso Universidade da Coruña F Departamento de Computación 25 2.2. Cuanticadores Cuanticador universal ∀: análogo del ∃. (∀I ∈ [m, ni : αI ) = ¬(∃I ∈ [m, ni : ¬αI ) = ¬(¬αm ∨ ¬αm+1 ∨ · · · ∨ ¬αn−1) = αm ∧ αm+1 ∧ · · · ∧ αn−1 ¾ A qué equivale (∀I ∈ [m, mi : αI )? Cuanticador contador Ejemplo: ¾ Cómo expresar que cumple k es el q -ésimo menor valor αk ? Solución más cómoda. Denimos: (NI ∈ [m, ni : αI ) como el número de valores de I Atención: ( NI · · · ) es un que satisfacen término numérico, αI . no una fórmula que se pueda hacer cierta o falsa. Universidade da Coruña Departamento de Computación 26 2.2. Cuanticadores q -ésimo menor valor k que cumple αk : ((NI ∈ [m, ki : αI ) = q − 1) ∧ αk Podemos denir ∀ y ∃ como: (∃I ∈ [m, ni : αI ) = ((NI ∈ [m, ni : αI ) ≥ 1) (∀I ∈ [m, ni : αI ) = ((NI ∈ [m, ni : αI ) = n − m) Propiedad interesante: unión de rangos (∃I ∈ [m, ni : αI ) ∨ (∃I ∈ [n, pi : αI ) = (∃I ∈ [m, pi : αI ) (∀I ∈ [m, ni : αI ) ∧ (∀I ∈ [n, pi : αI ) = (∀I ∈ [m, pi : αI ) (NI ∈ [m, ni : αI ) + (NI ∈ [n, pi : αI ) = (NI ∈ [m, pi : αI ) Universidade da Coruña Departamento de Computación 27 2.3. Variables libres y ligadas Todo nombre x, I, n, pi, J, etc, que usemos debe estar claramente denido: 1. constante del programa (mayúsculas) 2. variable del programa (conjunto ID) (minúsculas) 3. índice de algún cuanticador (mayúsculas) ¾ Puede aparecer cualquier i o I en un estado s? Las variables de cuanticación son locales a la expresión cuanticada. (∃I ∈ [2, 5i : I = 3 ∗ x) Cambiar su nombre no afecta a cómo son interpretadas. Imaginemos s = {(x, 1), (y, 2)} (∃J ∈ [2, 5i : J = 3 ∗ x) (∃I ∈ [2, 5i : I = 3 ∗ y) (∃x ∈ [2, 5i : x = 3 ∗ x) Universidade da Coruña Departamento de Computación 28 2.3. Variables libres y ligadas ¾ cómo interpretar esta fórmula ? i < 2 ∧ (∃i ∈ [m, ni : i = 2 ∗ x) la i local la cambiamos por J i < 2 ∧ (∃J ∈ [m, ni : J = 2 ∗ x) Def. Decimos que i, m, n, x están libres y que J (2) está ligada en la fórmula (2) Universidade da Coruña Departamento de Computación 29 2.3. Variables libres y ligadas Denición de i libre en una expresión: 1. i es libre en i 2. i es libre en (α) sii lo es en α 3. i es libre en ⊗α sii lo es en α 4. i es libre en α⊗β 5. i es libre en (⊗j ∈ [m, ni : α) j y además es libre en Universidade da Coruña sii lo es en m, n ó α o en β sii no es la propia α. Departamento de Computación 30 2.3. Variables libres y ligadas Denición de i ligada en una expresión: 1. i está ligada en (α) sii lo está en α 2. i está ligada en ⊗α sii lo está en α 3. i está ligada en α⊗β 4. i está ligada al cuanticador en (⊗i ∈ [m, ni : α), sii lo está en siendo llamada esta expresión el 5. i está ligada en Universidade da Coruña m, n o en β ámbito de i (⊗j ∈ [m, ni : α) cuanticador) si lo está en α o (aunque a otro α Departamento de Computación 31 2.3. Variables libres y ligadas Ejemplos: 2 ≤ m < n ∧ (∀i ∈ [2, mi : m/i 6= 0) 2 ≤ m < n ∧ (∀n ∈ [2, mi : m/n 6= 0) (∃i ∈ [1, 25i : 25/i = 0) ∧ (∃i ∈ [1, 25i : 26/i = 0) (∃t ∈ [1, 25i : 25/t = 0) ∧ (∃i ∈ [1, 25i : 26/i = 0) (∃i : 1 ≤ i < 25 : 25/i = 0 ∧ 26/i = 0) (∀m ∈ [n, n + 6i : (∃i ∈ [2, mi : m/i = 0)) (∀m ∈ [n, n + 6i : (∃n ∈ [2, ni : m/n = 0)) (∃k ∈ [0, ni : P ∧ Hk (T )) ∧ k > 0 (∀j ∈ [0, ni : (∃t ∈ [j + 1, mi : (∀k ∈ [0, ni : F (k, t)))) Universidade da Coruña Departamento de Computación 32 2.4. Sustitución textual Será usada para las instrucciones de asignación Def. αex se obtiene sustituyendo en la expresión todas las apariciones libres del identicador expresión x α por la e. Ejemplos: (x ∗ y)xz = (z ∗ y) (x ∗ y)xx+1 = ((x + 1) ∗ y) Universidade da Coruña Departamento de Computación 33 2.4. Sustitución textual Sea α la expresión: α : x < y ∧ (∃I ∈ [0, ni : I + x < y) ∨ b más ejemplos: αzx = z < y ∧ (∃I ∈ [0, ni : I + z < y) ∨ b y αx+y = x<x+y∧ (∃I ∈ [0, ni : I + x < x + y) ∨ b y (αw∗z )za+u = (x < w ∗ z ∧ (∃I ∈ [0, ni : I + x < w ∗ z) ∨ b)za+u = x < w ∗ (a + u) ∧ (∃I ∈ [0, ni : I + x < w ∗ (a + u)) ∨ b αkI = α Universidade da Coruña Departamento de Computación 34 2.4. Sustitución textual Problemas: 1. Las variables libres en ligadas en en α. αex. e no pueden convertirse en Para evitarlo, renombrar la ligada Ejemplo: αIx = I < y ∧ (∃J ∈ [0, ni : J + I < y) ∨ b 2. La expresión αex debe ser correcta semánticamen- te. Ejemplo: α3b = x < y ∧ (∃j ∈ [0, ni : j + i < y)∨ 3 (c[i])c3 = 3[i] son sustituciones Universidade da Coruña no válidas. Departamento de Computación 35 2.4. Sustitución textual Denimos de las xi ,...,xn αex11,...,e n como la sustitución simultánea por las expresiones ei. Ejemplos: (x + y)x,y 3,c = 3 + c (x + y)x,y y+1,c = y + 1 + c ((x + y)xy+1)yc = c + 1 + c En general: x,y αu,v 6= (αux)yv . Mismas restricciones que para el caso simple: 1. no ligar variables libres en las 2. αex ei debe ser semánticamente correcta Universidade da Coruña Departamento de Computación 36 2.4. Sustitución textual Estados de α y Def. El estado pasa a valer αex (s; x : v) es igual a s, excepto que x v: s − {(x, . . . )} ∪ {(x, v)} Una asignación x := e aplicada en s resultará en (s; x : s(e)). ¾ Quién es (s; x : s(x))? Propiedades: i) x s(αex) = s(αs(e) ) ii) Sea s0 = (s; x : s(e)). Entonces s0(α) = s(αex) iii) Dadas dos listas de identicadores mente excluyentes: Universidade da Coruña x y u mutua- (αux)ux = α Departamento de Computación 37 Ejemplos Dado s = {(x, 5), (y, 6), (b, T )} 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) Universidade da Coruña calcular los estados: Departamento de Computación 38 2.5. Otros cuanticadores ( P 1. 2. ( 2. se dene como: ( P I ∈ [m, mi : αI ) = 0 ( P I ∈ [m, k + 1i : αI ) = ( P I ∈ [m, ki : αI ) + αk , Q 1. I ∈ [m, ni : αI ) I ∈ [m, ni : αI ) k ≥ m. se dene como: ( Q I ∈ [m, mi : αI ) = 1 ( Q I ∈ [m, k + 1i : αI ) = ( Q I ∈ [m, ki : αI ) ∗ αk , Universidade da Coruña para para k ≥ m. Departamento de Computación 39 2.6. Funciones y predicados auxiliares Podremos hacer uso de predicados auxiliares. Ejemplo: def primo(X) = X : integer ∧ X > 0 ∧ (∀I ∈ [2, Xi : X mod I 6= 0) o de funciones auxiliares como: def abs(X) = X si −X en otro caso X≥0 La denición puede ser inductiva (recursiva). Ejemplo: 1 def f ibo(I) = 1 f ibo(I − 1) + f ibo(I − 2) Universidade da Coruña si I=1 si I=2 si I>2 Departamento de Computación 40 Tema 3. Arrays var b : array [0 : 2] of integer b[0 : 2] : integer Dos formas de entender el array: 1. Son varios identicadores clasicados por un índice: b[0], b[1], b[2]. Ejemplo de estado: 2. s = {(b[0], 4), (b[1], −2), (b[2], 7)} Es un solo identicador b cuyos valores son fun- ciones: b : {0, 1, 2} −→ integer 0 7−→ 4 1 7−→ −2 2 7−→ 7 Ejemplo de estado: Universidade da Coruña s = {(b, (4, −2, 7))} Departamento de Computación 41 Tema 3. Arrays Notación b.inf y b.sup son los valores extremos del índice de posiciones del array. En el ejemplo: b.inf = 0, b.sup = 2 dominio(b) = {i | b.inf ≤ i ≤ b.sup} ¾ Qué hace b[1] := 8? 1. cambiar el valor de b[1] 2. cambiar el valor de b El array (b; i : e) por por 8 (4, 8, 7) es tal que: (b; i : e)[j] = e si i = j b[j] si i 6= j (b; i : e; j : f ; k : g) = (((b; i : e); j : f ); k : g) s(b[15]) = U Universidade da Coruña (ya que 15 6∈ dominio(b)). Departamento de Computación 42 Tema 3. Arrays Predicado auxiliar perm(b, c) denota que c es permu- tación de b. Ejemplo: b[0 : 2] = (4, 8, 7). cierto para los valores de Entonces perm(b, c) es c: (4, 8, 7), (4, 7, 8), (8, 4, 7), (8, 7, 4), (7, 4, 8), (7, 8, 4) Ejemplo típico de simplicación: (b; i : 5)[j] = 5 Universidade da Coruña Departamento de Computación 43 Tema 3. Arrays Algunas abreviaturas: def b[1 : 4] = x = (∀I ∈ [1, 4] : b[I] = x) def b[1 : 4] 6= x = (∀I ∈ [1, 4] : b[I] 6= x) def b[0 : 3] ≤ b[3 : 6] = (∀I ∈ [0, 3], J ∈ [3, 6] : b[I] ≤ b[J]) def ¬(b[1 : 4] = x) = (∃I ∈ [1, 4] : b[I] 6= x) Universidade da Coruña Departamento de Computación 44 Tema 3. Arrays 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)) Universidade da Coruña Departamento de Computación 45 Tema 3. Arrays Def. un selector σ corchetes. Ej: ε es una secuencia de índices entre [i][j][k]. denota el selector nulo. Def. Denimos (b; σ : e) como: (b; ε : e) = e (b[j]; σ : e) si i = j (b; [i]σ : e)[j] = b[j] si i 6= j Universidade da Coruña Departamento de Computación 46 Tema 4. Guarded Command Language Podríamos usar Pascal o C. Por comodidad usamos Guarded Command Language [Dijkstra76]: 1. Sintaxis simple y muy reducida 2. Más cómodo para demostración formal 3. Asignaciones simultáneas, no-determinismo Semántica operacional: la usaremos para describir el funcionamiento de cada instrucción. Denimos una relación hestado , instr i 7→ estado . Ejemplo: h{(x, 1), (y, 2)}, “x := 0”i 7→ {(x, 0), (y, 2)} Universidade da Coruña Departamento de Computación 47 4.1. Sintaxis Denimos instrucción como una de las siguientes estructuras: 1. skip 2. abort 3. x1, . . . , xn := α1, . . . , αn 4. S 1 ; S2 5. if 6. do B1 → S1| . . . |Bm → Sm donde αi y B1 → S1| . . . |Bm → Sm m ≥ 0, xi od son variables (o referencias a arrays), son expresiones, Si Bi son fórmulas (sin cuanticadores) son a su vez instrucciones. Universidade da Coruña Departamento de Computación 48 4.2. Semántica operacional hs, “skip”i 7→ s hs, “abort”i 67→ s0 hs, (S1; S2)i 7→ s0 para cualesquiera sii hs, S1i 7→ s00 y s y s0 hs00, S2i 7→ s0 hs, “x := α ”i 7→ (s; x : s(α)) siempre que Ejemplos. Dados x, y : integer s(α) ∈ rango(x) 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 Universidade da Coruña Departamento de Computación 49 4.2. Asignación múltiple 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 asig- na 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)} Universidade da Coruña Departamento de Computación 50 4.2. Asignación: uso de arrays Dado un selector σ = [e1][e2] . . . [en] donde cada son expresiones, denimos su evaluación en ei s: def s(σ) = [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 to α como σ ei ∈ dominioi(x) y α ∈ rango(x). Tanse 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→ Universidade da Coruña no hay estado sigte. Departamento de Computación 51 4.2. Asignación general La descripción completa nal 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: σi 1. Se evalúan todos los selectores 2. Se evalúan todas las expresiones 3. Se asigna de izquierda a derecha Universidade da Coruña en αi s en s Departamento de Computación 52 4.2. Asignación 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 Universidade da Coruña Departamento de Computación 53 4.2. Instrucción condicional instrucción condicional tiene la forma: B1 → S1 Def. Una if | B2 → S2 | .. . | Bn → Sn 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 tras que Universidade da Coruña BB denota toda la instrucción, mien- es abreviatura de B1 ∨ B2 ∨ · · · ∨ Bn. Departamento de Computación 54 4.2. Instrucción condicional: ejecución. hs, IF i 7→ s0 se da siempre que: 1. No existe guarda 2. s0 Bi tal que s(Bi) = U es un estado tal que, para alguna rama s(Bi) = T y además i: hs, Sii 7→ s0. En otras palabras: Bi, s(Bi) = U , 1. Si para algún 2. Si no existe algún 3. Toma uno cq. de los Universidade da Coruña aborta. Bi, s(Bi) = T Bi aborta. ciertos y ejecuta Si . Departamento de Computación 55 4.2. Instrucción condicional. Ejemplo: mirar qué sucede al ejecutar → x := 1 if a=1 | a/b > 0 → x := 2 | a/b < 0 → x := 3 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 Universidade da Coruña Departamento de Computación 56 4.2. Instrucción iterativa. instrucción iterativa tiene la forma: B1 → S1 Def. Una do | B2 → S2 | .. . | Bn → Sn od con n ≥ 0. Llamamos DO hs, DO i 7→ s0 se da siempre que: 1. No existe guarda 2. s0 a) Bi tal que s(Bi) = U es un estado tal que: existe guarda además b) a toda la instrucción. y hs, (Si; DO )i 7→ s0 todo guarda Universidade da Coruña s(Bi) = T s(Bi) = F y s0 = s. Departamento de Computación 57 4.2. Instrucción iterativa. En otras palabras: Bi, s(Bi) = U , 1. Si para algún 2. Si no existe algún estado 3. aborta. Bi, s(Bi) = T , naliza en el s. Toma uno de los estado resultante Bi s0 , ciertos, ejecuta Si y, en el vuelve a ejecutar DO . Se puede reescribir con una sola condición, usando un if en el cuerpo: do BB → B1 → S1 if | B2 → S2 | .. . | Bn → Sn od Universidade da Coruña Departamento de Computación 58 4.2. Instrucción iterativa. Ejemplo: ejecutar los programas: do i/abs(i) = 1 → i := i − 2 | i/abs(i) = −1 → i := i + 2 od do i 6= 0 cand i/abs(i) = 1 → i := i − 2 | i 6= 0 cand i/abs(i) = −1 → i := i + 2 od en s = {(i, 6)}, s0 = {(i, 3)}. Universidade da Coruña Departamento de Computación 59 4.3. Transiciones de estados. Trayectoria: secuencia de estados (generada por un s0 −→ s1 −→ . . . −→ sn programa): 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= Dos programas estado inicial trayectoria nita. S y S 0 son equivalentes sii para todo s0 : 1. hs0, Si 7→ sn 2. ejecutar en s0 Universidade da Coruña S en sii s0 hs0, S 0i 7→ sn puede no terminar sii ejecutar S0 puede no terminar. Departamento de Computación 60 4.3. Transiciones de estados. ¾ 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 Universidade da Coruña Departamento de Computación 61 4.3. Transiciones de estados. Traza: es una secuencia ordenada de instrucciones (atómicas) que ejecuta un programa. La misma traza puede ser debida a distintas trayectorias. Dos trayectorias distintas para el mismo s0 ⇒ trazas distintas. Programa determinista: aquel que para cualquier inicial s0 genera (como mucho) una única traza. ⇒ mismo s0 , mismo s0, varias trayec. ⇒ varias trazas ⇒ no deter- varias trazas no determinista minista. mismo s0 , Universidade da Coruña única trayec. 6⇒ determinista. Departamento de Computación 62 4.4. Funciones y procedimientos parámetros resultado z }| { f (v1 : t1; . . . ; vn : tn) func ret z }| { (r : t) .. . Ejemplos: func abs(x : integer) ret (a : integer) x ≤ 0 → a := −x if | x ≥ 0 → a := x func f act(i : integer) ret (f : integer) i = 0 → f := 1 if | i > 0 → f := f act(i − 1) ∗ i Universidade da Coruña Departamento de Computación 63 4.4. Funciones y procedimientos proc valor z referencia }| { z }| { 0 0 0 0 f (v1 : t1; . . . ; vn : tn; var v1 : t1; . . . ; 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 Universidade da Coruña Departamento de Computación 64 4.4. Funciones y procedimientos Ejercicios: 1. Dado un número un array 2. x, devolver la primera posición i en b[0 : n − 1] Insertar un elemento nado desde 0 hasta 3. tal que b[i] ≥ x. x en un array b[0 : n − 1] orde- n − 2. Programar el procedimiento div(n, d, c, r) de modo recursivo. 4. Función recursiva para el máximo común divisor mcd(a, b). Universidade da Coruña Departamento de Computación 65 Tema 5. Aserciones Dado un programa sión {Q} S {R} Si S S , y las fórmulas Q y R la expresignica: arranca en un estado que satisface Q, entonces se garantiza que termina, y lo hace en un estado que satisface Q: precondición o R: postcondición Importante: R. aserción de entrada o aserción de salida o de resultado {Q} S {R} es también una fórmula de predicados. Intentaremos probar que es una tautología. Método: mediante sustituciones se transforma en una fórmula para el estado inicial. Universidade da Coruña Departamento de Computación 66 Tema 5. Aserciones Def. La especicación formal de un problema consis- te 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 especicación incluiremos a veces restricciones: a y b son jas. 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} Universidade da Coruña Departamento de Computación 67 Tema 5. Aserciones Un intercambio se puede expresar como: {x = X ∧ y = Y } swap {y = X ∧ x = Y } Que el array nalice ordenado: {N ≥ 0 ∧ b[0 : N ] = B} S {R : perm(b, B) ∧ (∀I ∈ [0, N − 1] : b[I] ≤ b[I + 1])} Universidade da Coruña Departamento de Computación 68 Tema 5. Aserciones Ejemplos: M es el máximo valor max(b[0 : N − 1], M ): (∀I ∈ [0, N i : M ≥ b[I]) ∧ (∃I ∈ [0, N i : M = b[I]) p es la posición del máximo valor de b[0 : N − 1]: 0 ≤ p < N ∧ (∀I ∈ [0, N i : b[p] ≥ b[I]) p es la 4a posición donde aparece el valor máximo M: 0 ≤ p < N ∧ max(b, b[p]) ∧ (NI ∈ [0, pi : b[I] = b[p]) = 3 M es el 3er valor más pequeño del array b[0 : N − 1]: (∃I ∈ [0, N i : M = b[I]) ∧ (NI ∈ [0, N i : b[I] < M ) = 2 p (mayor que 1) es número primo: p > 1 ∧ (∀I ∈ [2, pi : p mod I 6= 0) Universidade da Coruña Departamento de Computación 69 5.1. Anotación de un programa Anotar = toda instrucción anqueada por aserciones: {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} signican P ⇒Q {P 1} t:=x; {P 2}{P 3} x:=y; {P 4} es igual que: {P 1} t:=x; {P 2} P2 ⇒ P3 {P 3} x:=y; {P 4} Universidade da Coruña Departamento de Computación 70 5.2. Precondición más débil: wp Def. Weakest Precondition Dado un programa S y una fórmula todos los estados iniciales S i) ii) en S s0 , s0 , R, wp(S, R) son tales que si se ejecuta se garantiza que: termina (en un estado sn ) sn(R) = T 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) La fórmula debe ser la i ≤ −10 vale como precondición, pero no es la más débil que satisface Universidade da Coruña más débil posible. Por ejemplo i) y ii): (i ≤ −10 ⇒ i ≤ 0). Departamento de Computación 71 5.2. Precondición más débil: wp Ejemplo: supongamos que if x≥y S es z := x then else z := y 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) ¾ Tiene sentido wp(S, T )? Indica en qué condiciones se garantiza la terminación del programa. Ejemplo: wp(“while T Universidade da Coruña do skip”, T ) = F Departamento de Computación 72 5.2. Precondición más débil: wp Importante: {Q} S {R} es cierto si y sólo si: EST (Q) ⊆ wp(S, R) es decir, si que wp está en formato fórmula", exigimos Q ⇒ wp(S, R) sea una tautología. Cuando esto sucede, decimos que el programa tisface la corrección total respecto a La corrección parcial de S Q respecto a y S sa- R, se R. Q y denota: Q {S} R y Equivale a armar: 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 Universidade da Coruña S. Departamento de Computación 73 5.2. Precondición más débil: wp Ejemplo: T {while T do skip}T es tautología. Propiedades: 1. wp(S, F ) = F 2. wp(S, α) ∧ wp(S, β) = wp(S, α ∧ β) 3. Si 4. wp(S, α) ∨ wp(S, β) ⇒ wp(S, α ∨ β) 5. wp(S, α) ∨ wp(S, β) ⇐ wp(S, α ∨ β), si α⇒β S entonces wp(S, α) ⇒ wp(S, β) es determinista. Universidade da Coruña Departamento de Computación 74 Tema 6. Vericación formal de programas. Caracterizar las instrucciones mediante su mántica wp (se- 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 Universidade da Coruña Departamento de Computación 75 6.1. Asignación. Asignación x := e". El identicador x toma el valor de la expresión wp(“x := e”, R) = dominio(e) donde los s dominio(e) tal que cand e. Rex es una expresión que cubre todos 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 wp(“x := b[i]”, x = b[i]) = dominio(i, b) Recordar: si Universidade da Coruña s(i) está fuera de rango, a/b 6= 1 cand T s(b[i]) = U Departamento de Computación 76 6.1. 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)))) lo simplicamos como: {wp1} S1 {wp2} S2 {wp3} S3 {wp4} S4 {R} {wp1} S1; S2; S3; S4 {R} Universidade da Coruña Departamento de Computación 77 6.1. Asignación. La asignación te x := e, x1, . . . , xn := e1, . . . , en, o simplemen- donde las xi son distintas, se dene: wp(“x := e”, R) = dominio(e) cand Rex Ejemplos: x, y := y, x x, y, z := y, z, x wp “s, i := s + b[i], i + 1”, i > 0 ∧ s = (ΣJ ∈ [0, ii : 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? Universidade da Coruña Departamento de Computación 78 6.1. Asignación. Interesante: también se puede usar wp para escribir el programa. Ejemplo: Queremos i := m + 1 pero que n siga indi- cando el número de elementos. Universidade da Coruña Departamento de Computación 79 6.1. 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 = α) a pero esa ` ' es en el estado inicial. Universidade da Coruña Departamento de Computación 80 6.1. Asignación. Arrays: se usa la interpretación como función: wp(“b[i] := e”, R) = wp(“b := (b; i : e)”, R) = dominio((b; i : e)) = enrango(i, b) cand cand cand b R(b;i:e) dominio(e) b 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) Universidade da Coruña Departamento de Computación 81 6.1. Asignación. Asignación general: x1σ1, . . . , xnσn := e1, . . . , en xσ := e Denimos: def wp(“xσ := e”, R) = Rexσ Problema: hay que redenir la sustitución textual. xσ ) no son identicadores. ( 1. Para ello: reagrupar todas las referencias al mismo array, respetando el orden, 2. aplicar sustitución de arrays. Universidade da Coruña Departamento de Computación 82 6.1. 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 x R1,2 = R(x;ε:1;ε:2) = R2x Universidade da Coruña Departamento de Computación 83 6.2. Instrucción condicional. Denición: wp(IF , R) = dominio(BB) ∧ BB ∧ ∧(B1 ⇒ wp(S1, R)) ∧ . . . ∧(Bn ⇒ wp(Sn, R)) Probar i) ii) iii) Q ⇒ wp(IF , R) equivale a probar: Q ⇒ dominio(BB) Q ⇒ BB Q ∧ Bi ⇒ wp(Si, R) Universidade da Coruña Departamento de Computación 84 6.3. Instrucción iterativa. Precondición más débil de un DO : i) Para acabar en 0 iteraciones: H0(R) = ¬BB ∧ R ii) Para acabar en k>0 iteraciones: Hk (R) = wp(IF , Hk−1(R)) iii) Para acabar en cualquier número de iteraciones: wp(DO , R) = (∃k : 0 ≤ k : wp(IF , Hk (R))) Problema: no aplicable en la práctica. El desarrollo de wp(DO , R) es recursivo y puede ser que nunca terminemos de elaborarlo. Universidade da Coruña Departamento de Computación 85 6.3. Instrucción iterativa. Utilizaremos la siguiente técnica: 1. 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). 2. Para demostrar que el bucle naliza: buscaremos una función t, llamada función cota, que en cada iteración sea positiva y decreciente. 3. Ejemplo: i, s := 1, b[0]; do i < 11 → i, s := i + 1, s + b[i] od {R : s = (ΣK ∈ [0, 11i : b[K])} Universidade da Coruña Departamento de Computación 86 6.3. Instrucción iterativa. Otro ejemplo: {b ≥ 0} x, y, z := a, b, 0; y > 0 ∧ par(y) → y, x := y/2, x + x do | impar(y) → y, z := y − 1, z + x od {R : z = a ∗ b} Teorema. Dados DO , P y t tales que: 1. P ∧ Bi ⇒ wp(Si, P ) 2. P ∧ BB ⇒ (t > 0) 3. P ∧ Bi ⇒ wp(“t1 := t; Si”, t < t1) para todo i ∈ [1, n] para todo i ∈ [1, n] entonces Universidade da Coruña P ⇒ wp(DO , P ∧ ¬BB) Departamento de Computación 87 6.3. Instrucción iterativa. Normalmente escribiremos: {Q : . . . } {inv P : . . . } {cota t : . . . } do B1 → S1| . . . |Bn → Sn od {R : . . . } Método de prueba: demostrar los cinco puntos: 1. P 2. {P ∧ Bi}Si{P } 3. P ∧ ¬BB ⇒ R, 4. P ∧ BB ⇒ (t > 0), 5. {P ∧ Bi}t1 := t; Si{t < t1} cierto justo antes de empezar el bucle, Universidade da Coruña para cada rama, para cada rama. Departamento de Computación 88 Tema 7. 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 R y, en menor medida, Veremos posibles especicación. Sobre todo Q. estrategias para desarrollar el pro- grama a partir de la especicación. Universidade da Coruña Departamento de Computación 89 7.1. Estrategias para el IF . Estrategia 1. Para construir un IF : 1. Identicar una instrucción S que haga cierto R en algún(os) caso(s). 2. Encontrar una condición crear una rama del IF 3. Si la precondición Q B con t.q. B ⇒ wp(S, R) y B → S. 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: hacer las condiciones custodia tan fuertes como sea posible. Universidade da Coruña Departamento de Computación 90 7.2. Estrategias para el DO . Estrategia 2 para construir un DO a partir de y P t: B Identicar una condición 2. Desarrollar el cuerpo del bucle de modo que: a) la cota b) la invariante t tal que P ∧ ¬B ⇒ R. 1. disminuya, P se mantenga cierta. Principio: hacer la custodia B tan débil como sea posible. Universidade da Coruña Departamento de Computación 91 7.2. Estrategias para el DO . Estrategia 3. Para construir un DO a partir de y 1. t: Identicar casos teniendo 2. P Cuando Universidade da Coruña Bi → Si que decrementan t man- P. P ∧ ¬BB ⇒ R, parar. Departamento de Computación 92 7.3. Construcción de invariantes. Teoría del globo .IN I = estados iniciales (antes del bucle), R=poscondición. P debe ser cierta antes y des- pués: La ejecución desina Para obtener tendremos: Universidade da Coruña P hasta llegar a R: P : inar o debilitar R. En cada iteración Pi = P ∧ 0 ≤ t ≤ ti. Departamento de Computación 93 7.3.1. Reducir una conjunción. Reducir algo como A∧B∧C a A ∧ C. Ejemplo: Aproximar la raíz cuadrada de Estrategia 4. Al borrar un fragmento junción en R para derivar fragmento como custodia n. B de una con- P , usar la negación de ese B del bucle. Ejemplo: búsqueda lineal. Estrategia 5. Para encotrar un valor máximo) mínimo (resp. que satisface una propiedad, comenzar por la cota inferior (resp. superior) e ir incrementando (resp. decrementando). Universidade da Coruña Departamento de Computación 94 7.3.2. Cambiar una constante por una variable. Estrategia 6. Cambiar un valor constante de R por un nuevo identicador. Fijar el rango del identicador: al acabar, debe ser igual a la constante. Ejemplos: • Suma de elementos de un array. • Aproximar • Buscar la raíz cuadrada de n. la mayor meseta. Principio. Introducir una variable sólo si es necesa- rio. Ej: 1. debilitar R, cambiando constante por nueva varia- ble 2. optimizar un cálculo local Universidade da Coruña Departamento de Computación 95 7.3.3. Aumentar el rango de una variable. Estrategia 7. Tomar una variable de R y aumentar los posibles valores que puede tomar. Ejemplos: • Búsqueda lineal. • Pertenencia a tres listas ( wellfare crook). Principio. Usar deniciones de relaciones y nombres de valores concretos, para simplicar la prueba. Universidade da Coruña Departamento de Computación 96 7.3.4. Combinar pre y postcondiciones. Cuando hay que cambiar el contenido de las variables, los métodos anteriores no suelen ser sucientes. Los podemos combinar con: Estrategia 8. Buscar una invariante que generalice la pre y la postcondición. Ejemplos: • Insertar espacios. • Intercambiar Universidade da Coruña secciones de igual longitud. Departamento de Computación 97 7.3.5. Evitar posiciones aisladas. En P, si es posible, evitar expresiones sobre una po- sición concreta, sustituyéndolas por Ejemplo: (ejercicio 7.1.) no denido cuando intervalos. b[i] > b[0 : i − 1] se vuelve i = n. Si lo cambiamos por b[i : n − 1] > b[0 : i − 1], cuando i = n la fórmula pasa a ser trivialmente cierta (∀ con rango vacío). Universidade da Coruña Departamento de Computación 98 7.4. Funciones cota. La cota sirve para: 1. Probar que el bucle termina 2. Proporcionar una cota superior del número de iteraciones. Ejemplo: programas para √ n 1. programa a := a + 1, 2. programa d := (a + b)/2, también cota √ t : ceil( n) − a cota t : b − a + 1, pero t : ceil(log(b − a)) Estrategia 8. Identicar la parte no resuelta del problema y buscar una expresión matemática que permita medirla. Ejemplo: buscar en un array bidimensional. Universidade da Coruña Departamento de Computación 99 7.4. Funciones cota. Estrategia 9. Detectar orden lexicográco en tuplas de números o de índices (especialmente para arrays). (a0, a2, . . . , an−1) < (b0, b2, . . . , bn−1) se dene como: (∃I ∈ [0, ni : (∀J ∈ [0, Ii : aJ = bJ ) ∧ aI < bI ) Teorema. Sea una tupla ~a = (a0, . . . , an−1) de ex- presiones usadas en un bucle. Supongamos que cada ai se mueve en mi ≤ ai ≤ Mi y que ~a decrece lexico- grácamente. Entonces: 1. el bucle termina, y 2. una cota válida es t= (ΣI ∈ [0, ni : (aI −mI )∗(ΠJ ∈ [I+1, ni : MJ −mJ +1)) Ejemplos: array bidimensional, ordenar una 4-tupla, problema de los trenes. Universidade da Coruña Departamento de Computación 100 Tema 8. Procedimientos, funciones y recursividad. 8.1. Funciones Las deniciones tienen la forma: func f (X) ret r {Q} S {R} Por simplicidad, supondremos que: En Q sólo aparecen libres las X. En R sólo aparecen libres las X Las variables internas de f y r. no se usan en el resto del programa. Universidade da Coruña Departamento de Computación 101 8.1. Funciones Ejemplo: func abs(X) ret r {Q : T } X ≥ 0 → r := X if | X ≤ 0 → r := −X {R : X ≥ 0 ∧ r = X ∨ X ≤ 0 ∧ r = −X} Las llamadas tienen la forma e yσ := α f (e) son expresiones del mismo tipo que yσ coincide en tipo con α f (e) donde: X. m. es una expresión que contiene a f (e) una sola vez. f no aparece en Universidade da Coruña σ ni en e. Departamento de Computación 102 8.1. 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; Universidade da Coruña Departamento de Computación 103 8.1. Funciones La llamada y := f (e) equivale a ejecutar: X := e; S; y := α(r) Supongamos que hemos demostrado {Q} S {R}. Pa- ra demostrar: {G} y := α f (e) {H} debemos realizar los siguientes pasos: 1. G ⇒ QX e 2. y G ∧ ReX ⇒ Hα(r) Ejemplo: demostrar {a > b ∧ c > 0} b := c ∗ abs(a − b) {b > 0} Universidade da Coruña Departamento de Computación 104 8.2. Procedimientos Las deniciones tienen la forma: proc p(X; var r) {Q} S {R} De nuevo, suponemos que: En Q sólo aparecen libres las X. En R sólo aparecen libres las X Las variables internas de p y r. no se usan en el resto del programa. y además: Las variables la llamada r funcionan por copia local. Esto es, p(e, y) equivale a: X, r := e, y; S; y := r Universidade da Coruña Departamento de Computación 105 8.2. Procedimientos Ejemplo: proc incr(X; var r) {Q : r = Z} r := r + X; {R : r = Z + X} Supongamos que hemos demostrado ra demostrar: {G} y := f (e) {H} {Q} S {R}. Padebemos realizar los siguientes pasos: 1. G ⇒ QX,r e,y 2. G ∧ ReX ⇒ Hry Ejemplo: demostrar {a ≥ 0 ∧ b = B} incr(a + 1, b) {b > B} Universidade da Coruña Departamento de Computación 106 8.3. Recursividad Def.: la función (o procedimiento) f es recursiva si su ejecución puede producir una nueva llamada a f. Ejemplo: func if f act(X) ret r X = 0 → r := X | X > 0 → r := X ∗ f act(X − 1) Recursividad directa: la llamada a el cuerpo de Universidade da Coruña f. Ejemplo: f se produce en f act. Departamento de Computación 107 8.3. Recursividad Recursividad indirecta: f llama a otra función ya ejecución acaba nalmente llamando a f g cu- de vuelta. Ejemplo: func if par(X) ret r : boolean X = 0 → r := T | X > 0 → r := impar(X − 1) func if impar(X) ret r : boolean X = 0 → r := F | X > 0 → r := par(X − 1) Universidade da Coruña Departamento de Computación 108 8.3. Recursividad Dentro de recursividad directa: simple o lineal: cada ejecución del cuerpo de nera como mucho una nueva llamada a nivel). Ejemplo: f f act. suponer hacer uso de if ge- (a primer múltiple o no lineal: ejecutar el cuerpo de func f f f ibo(X) f puede dos o más veces. Ejemplo: ret r X = 0 → r := 0 | X = 1 → r := 1 | X > 1 → a := f ibo(X − 1); b := f ibo(X − 2); r := a + b Universidade da Coruña Departamento de Computación 109 8.3. Recursividad Dentro de recursividad directa lineal: nal (tail): la llamada es la última instrucción ejecutada. Ejemplo: f act. Ejemplo de no nal: func if | max(B[0 : N − 1], I, D) ret r I<D → r := max(B, I + 1, D) I=D → r := B[I] ; B[I] > r → r := B[I] if | B[I] <= r → skip Universidade da Coruña Departamento de Computación