Algoritmos y Estructura de Datos I

Anuncio
Algoritmos y Estructura de Datos I
Ciclos I
Lean
Viernes 30 de Septiembre de 2016
Hoy nos toca...
I
Ciclos 101
I
Teorema del invariante. ¿Qué era eso?
I
Definir componentes del ciclo
1 / 13
Estructura del ciclo
Sintaxis:
while (B) {
h cuerpo del ciclo i
}
I
B: expresión booleana del lenguaje de programación.
Se la llama guarda.
2 / 13
Estructura del ciclo
Sintaxis:
while (B) {
h cuerpo del ciclo i
}
I
{h cuerpo del ciclo i}: es un bloque de instrucciones entre
llaves.
I
Se repite mientras valga la guarda B.
I
Puede ejecutarse cero o más veces.
I
Cada repetición se llama una iteración.
3 / 13
Estructura del ciclo
Sintaxis:
while (B) {
h cuerpo del ciclo i
}
I
La ejecución del ciclo termina si y sólo si el ciclo se repite una
cantidad finita de veces. Esto ocurre si y sólo si la guarda B
llega a ser falsa.
I
Si el ciclo termina, el estado resultante es el estado posterior a
la última instrucción del cuerpo del ciclo.
4 / 13
Repaso: Teorema del invariante
I
Necesitamos poder hacer demostraciones en programas que
tienen ciclos
I
Por eso, el teorema del invariante va a ser nuestra herramienta
favorita!
I
¿Cómo funciona?
I
Necesitamos una especificación del ciclo
Si demostramos la validez de 5 condiciones entonces
habremos probado
I
I
I
que el ciclo termina
que el ciclo es correcto con respecto a su especificación
5 / 13
Teorema del invariante: Especificación
I
PC (Bool): precondición del ciclo
I
QC (Bool): postcondición del ciclo
I
I (Bool): Si vale al comenzar el cuerpo del ciclo, entonces vale
después de ejecutar la última instrucción del cuerpo del ciclo
I
Expresión variante (v ) (Int): Usa variables del programa y
tiene que decrecer en cada iteración
I
Cota (c) (Int): Es un valor que si es alcanzado por la
expresión variante, garantiza que la ejecución sale del ciclo
6 / 13
Teorema del invariante: Condiciones
I
PC → I
I
(I ∧ ¬B) → QC
I
El invariante se preserva en la ejecución del cuerpo, i.e. si
I ∧ B vale en el primer estado del ciclo entonces I vale en el
último
I
v es decreciente, i.e. v @Eciclo1 > v @EcicloN
I
(I ∧ v ≤ c) → ¬B
7 / 13
Ejercicios
8 / 13
Máximo
problema maximo (a: [Z], n: Z) = res : Z {
requiere |a| > 0 ;
requiere n == |a| ;
asegura res ∈ a ∧ (∀i ← [0..|a|))res ≥ ai ;
}
int maximo(int a[], int n) {
int res = a[0];
int i = 1;
while (i < n) {
if (a[i] > res) {
res = a[i];
}
i++;
}
return res;
}
9 / 13
Máximo
int maximo(int a[], int n) {
int res = ...;
int i = ...;
while (...) {
...
}
return res;
}
Reescribir el código para que el ciclo se corresponda con la siguiente
función variante: fv = n/2 + 1 − i (cota: 0).
10 / 13
Duplicar
Implementar una función (y especificar su ciclo) que cumpla la
siguiente especificación:
problema duplicar (a: [Z], n: Z) {
requiere n == |a| ;
requiere n mod 2 == 0 ;
modifica a ;
asegura |a| == |pre(a)| ∧ (∀i ← [0.. |a|))ai == 2 ∗ pre(a)i ;
}
¿Y si queremos que el ciclo cumpla este invariante? (E es el estado
previo al ciclo):
I : 0 ≤ i ≤ n/2∧
(∀j ← [0..i))(aj == 2 ∗ a@Ej ∧ aj+n/2 == 2 ∗ a@Ej+n/2 )∧
(∀j ← [i..n/2))(aj == a@Ej ∧ aj+n/2 == a@Ej+n/2 )
11 / 13
Nuestro viejo y querido Fibo
Implementar una función (y especificar su ciclo) que cumpla la
siguiente especificación:
problema sucesionFibo (a: [Z], n: Z) {
requiere n == |a| ;
requiere n > 1 ;
modifica a ;
asegura |a| == |pre(a)| ∧ esSucesionFibo(a, n) ;
aux esSucesionFibo (a: [Z], n: Z) : Bool =
(∀i ← [0..n)) iesimoFibo(a, i) ;
aux iesimoFibo (a: [Z], i: Z) : Bool =
if i ≤ 1 then a[i] == 1 else a[i] == a[i − 1] + a[i − 2] ;
}
12 / 13
Descargar