Pulse aquí para obtener el archivo

Anuncio
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
Descargar