Diseño iterativo y Corrección de programas Orlando Arboleda Molina Juan Francisco Dı́az 5 de septiembre de 2005 Contenido 1. Computación iterativa 2. Correctitud 3. Invariantes de ciclo 1 1. Computación iterativa Una computación iterativa es aquella que durante su ejecución, utiliza espacio adicional constante, sin importar la duración de la computación. Una computación iterativa se caracteriza por comenzar en un estado inicial S0 , y transformar ese estado en un conjunto de estados intermedios hasta llegar a un estado final Sf S0 → S 1 → S 2 . . . → S f Todo estado debe caracterizarse por una condición que siempre se cumple y que se denomina Invariante. Tanto el estado inicial, como los intermedios, como el final siempre cumplen esa condición. 2 Ejemplo1:* Cálculo de Factorial 1. Entrada:N ≥ 0 2. Salida: resultado = N ! 3. Idea: Iteración ascendente: (0, 1) → (1, 1) → (2, 2) → (3, 6) → . . . → (N, N !) 4. Estado: Tupla de la forma (indice, resultado) tal que indice ≤ N ∧ resultado = indice! (Invariante) 5. Estado Inicial: indice = 0, resultado = 1 6. Estado Final indice = N 7. Transformación de estados: (indice, resultado) → (indice + 1, (indice + 1) ∗ resultado) 3 8. Algoritmo: FactorialAsc(int N) { int indice=0; int resultado=1; (almacenará el factorial) while !(indice = N ) { indice = indice + 1; resultado = indice ∗ resultado; } System.out.println(resultado); } Es correcto con respecto a su especificación? 4 Ejemplo2:* Cálculo de Factorial 1. Entrada:N ≥ 0 2. Salida: resultado = N ! 3. Idea: Iteración descendente: (N, N ) → (N −1, N ∗(N −1)) → (N −2, N ∗(N −1)∗(N −2)) . . . → (1, N !) 4. Estado: Tupla de la forma (indice, resultado) tal que indice ≥ 1 ∧ resultado = N ∗ (N − 1) ∗ (N − 2) ∗ . . . ∗ (indice) (Invariante) 5. Estado Inicial: indice = N, resultado = N 6. Estado Final indice = 1 7. Transformación de estados: (indice, resultado) → (indice − 1, resultado ∗ (indice − 1)) 5 8. Algoritmo: FactorialDesc(int N) { int indice=N; int resultado=N; (almacenará el factorial) while !(indice = 1) { indice = indice-1; resultado = indice*resultado; } System.out.println(result); } Es correcto con respecto a su especificación? En general el esquema de un algoritmo iterativo es el siguiente: S ← S0 While ! IsFinal(S) do S ← T ransf orm(S) 6 Ejemplo3:* Raı́z cuadrada 1. Entrada:X ≥ 0 ∧ X ∈ R ∧ δ > 0 2. Salida: a : |a2 − X| ≤ δ 3. Idea: Método de newton: Dado un real X empiece con una adivinanza a de la raı́z de X e iterativamente mejore a hasta que sea suficientemente buena. Cómo mejorar a? a0 = (a + X/a)/2 √ √ √ a − X > a0 − X ssi a 6= X 4. Estado: a > 0 5. Estado Inicial: a = 1,0 6. Estado Final a : |a2 − X| ≤ δ 7 7. Algoritmo: raizIterativa (double X, double delta) { double a=1.0; while ( !(Math.abs(X-a*a)/X)<=delta ) { a = (a + X/a)/2.0; } System.out.println(a); } Es correcto con respecto a su especificación? 8 2. Corrección Una especificación es la definición de un problema en términos de sus condiciones de entrada precondición y sus condiciones de salida postcondición Un algoritmo A es correcto con respecto a una especificación (Q la precondición y R la postcondición)si para cada conjunto de valores de entrada que cumplen la precondición, los valores de salida producidos cumplen la postcondición. Se notará: {Q}A{R} Dada una especificación (Q la precondición y R la postcondición) y un algoritmo iterativo A de la forma: S ← S0 While ! IsFinal(S) do S ← T ransf orm(S) con P como condición invariante, se puede concluir que {Q}A{R} si y solo si: 1. Inicialización {Q}S ← S0 {P}, es decir S0 cumple el invariante. 2. Invarianza {P}S ← T ransf orm(S) {P}, es decir la transformación conserva el invariante. 3. Exito P ∧ S es final =⇒ R 4. Terminación A termina Aplicar a los ejemplos anteriores 9 Ejemplo4: Considere el siguiente algoritmo: Computa(int A,int B) { 1 int res, i; 2 res=0; 3 i=1; 4 while ( i <= B ){ 5 i=i+1; 6 res=res+A; 7 } 8 System.out.println(res); 9} Si {Q: A, B ∈ R ∧ B > 0}, {R: res = P A ∗ B} y i−1 A} es el invariante del ciclo, {P: res = p=1 se tiene que {Q} Computa {R} ? Aplicando los pasos para verificar que un programa iterativo es correcto tenemos: 10 1. Inicialización: Antes de ingresar al ciclo tenemos que i = 1. Aplicando el invariante de ciclo tenemos que: P0 P Pi−1 A = 1−1 res = p=1 p=1 A = 0 valor de res (lı́nea 2) p=1 A = 2. Invarianza: Al inicio de la iteración i = k res = k−1 X A p=1 Al ejecutar esta iteración se tiene: res = res + A = k−1 X A+A= p=1 k X A (linea 6) p=1 e i = k + 1 (linea 5) Luego el invariante de ciclo se mantiene 3. Exito: El ciclo finaliza cuando i = B + 1. Como el invariante es cierto P se da que: P PB P (B+1)−1 i−1 A= B A = p=1 res = p=1 p=1 1 = A ∗ B p=1 A = A ∗ 4. Terminación: En cada paso la diferencia entre B e i disminuye, luego en algún momento finito i > B. Conclusión: {Q} Computa {R} 11 Ejemplo5:* Indicar pre y poscondición tal que Computa3 sea correcto con respecto a esa especificación y se enuncie lo que se caclula en A. Computa3(int N) { 1 int A,B,i,j; 2 A=0; 3 i=1; 4 while ( i <= N ){ 5 B=1; 6 j=1; 7 while ( j <= 3 ){ 8 B=B*i; 9 j++; 10 } 11 A=A+B; 12 i++; 12 } 14 System.out.println(.A=”+A); 15 } Invariante de ciclo: A = Pi−1 p=1 p 3 12 Ejemplo6:* Indicar pre y poscondición tal que Opera sea correcto con respecto a esa especificación y se enuncie lo que se caclula en D. Opera(int B, int N) { 1 int A, C, D; 2 3 4 5 6 7 8 9 10 11 D=0; A=1; C=N; while ( C >= 1 ){ A=A*B; D=D+A; C–; } System.out.println(”D=”+D); } Nota: En este caso la variable controla el ciclo(C) es decreciente PNque −C Invariante de ciclo: D = p=1 B p . (donde A = B N −C ) Ejemplo7: PN Elp procedimiento Opera sigue siendo correcto para computar p=1 B si se intercambian las lineas 6 y 7 ? 13 Ejemplo8: A partir del procedimiento indicado a continuación, que tiene como entrada un arreglo A indexado de la forma [1..n]. Indicar: 1. Invariante de ciclo para el iterador interno (linea 3) 2. Invariante de ciclo para el iterador externo (linea 2) 3. Que calcula ? void BS(int A[], int N) { 1 int i, j, aux; 2 for ( i=1; i < N ; i++) 3 for ( j=N; j > i ; j–) 4 if ( A[j] < A[j − 1] ){ 5 aux=A[j]; 6 A[j]=A[j-1]; 7 A[j-1]=aux; 8 } 9} 14