Introducción a la computación Charlie Estado Se denomina estado en un modelo de cómputo a un punto en la ejecución de un programa en dicho modelo. En el modelo de Von Neumann esto responde al valor de las variables, constantes y la instrucción del programa que corresponde a dicho punto de la ejecución. Especificación de algoritmos Especificar un algoritmo es describir qué es lo que hace a partir de detallar cuál es el estado posterior a su ejecución en función del estado anterior a la misma. pre = {precondición} P post = {postcondición} Instrucción (Otra oportunidad) Una instrucción es una operación que produce una transformación del estado en que se encuentra la ejecución del programa (recordar que la instrucción en la que se encuentra la ejecución es parte del estado y por lo tanto la alteración del flujo de control es una transformación del estado tanto como la modificación del contenido de una posición de . memoria) Corrección Repetición: while ([expr1][comp][expr2]) { [prog] } Supongamos que tenemos la siguiente situación, S1={...} while (cond){[prog]} S2={...} y queremos saber si el ciclo es correcto respecto de los estados S1 y S2. Luego, debemos ver que: Corrección Repetición: while ([expr1][comp][expr2]) { [prog] } Supongamos que tenemos la siguiente situación, S1={...} while (cond){[prog]} S2={...} y queremos saber si el ciclo es correcto respecto de los estados S1 y S2. Luego, debemos ver que: Pero primero... Invariante Un invariante de un programa/algoritmo es un predicado cuyo valor de verdad no se ve afectado a lo largo de la ejecución de dicho programa/algoritmo. Invariante Un invariante de un programa/algoritmo es un predicado cuyo valor de verdad no se ve afectado a lo largo de la ejecución de dicho programa/algoritmo. x=22; x=2*x; y=x/22; x=x+1; x>=22 && y < 3 Invariante Un invariante de un programa/algoritmo es un predicado cuyo valor de verdad no se ve afectado a lo largo de la ejecución de dicho programa/algoritmo. Invariante Un invariante de un programa/algoritmo es un predicado cuyo valor de verdad no se ve afectado a lo largo de la ejecución de dicho programa/algoritmo. x=1; y=0; while (x<11){ y=y+x; x++; } x<=11 && y == Sum (i, 1<=i<x) Invariante Un invariante de un programa/algoritmo es un predicado cuyo valor de verdad no se ve afectado a lo largo de la ejecución de dicho programa/algoritmo. Invariante Un invariante de un programa/algoritmo es un predicado cuyo valor de verdad no se ve afectado a lo largo de la ejecución de dicho programa/algoritmo. Un invariante va a ser la herramienta a partir de la cual transferiremos información desde el estado de comienzo de un ciclo hacia el estado de finalización. Función variante y cota A los efectos prácticos sólo nos interesará la corrección de algoritmos con lo que para que un ciclo sea correcto debe terminar. ¿Cómo garantizamos que un ciclo termina? Función variante y cota A los efectos prácticos sólo nos interesará la corrección de algoritmos con lo que para que un ciclo sea correcto debe terminar. ¿Cómo garantizamos que un ciclo termina? Demostrando que la condición del ciclo se hace falsa en algún momento. Función variante y cota Formalmente esto implica encontrar una función monótona decreciente para la que existe una cota que una vez alcanzada la condición del ciclo deja de valer... Función variante y cota Formalmente esto implica encontrar una función monótona decreciente para la que existe una cota que una vez alcanzada la condición del ciclo deja de valer... Dicho de otra forma: 這正式暗示查找級別存在的一個越來越少的單調 功能,并且一次到達,循環的情況是錯誤的 Función variante y cota Formalmente esto implica encontrar una función monótona decreciente para la que existe una cota que una vez alcanzada la condición del ciclo deja de valer... x=1; y=0; while (x<11){ y=y+x; x++; } f(x) = 11-x, cota: 0 Función variante y cota Formalmente esto implica encontrar una función monótona decreciente para la que existe una cota que una vez alcanzada la condición del ciclo deja de valer... x=1; y=0; while (x<11){ y=y+x; x++; } f(x) = 11-x, cota: 0 ¡Ahora sí! Función variante y cota Al final del día: lo que vamos a hacer es argumentar que existe un estado alcanzable en la ejecución de nuestro programa para el cual la condición del ciclo deja de ser verdadera y consecuentemente, el ciclo termina. Corrección Repetición: while ([expr1][comp][expr2]) { [prog] } S1={...} while (cond){[prog]} S2={...} 1.- Si vale S1, entonces vale Inv Inv && cond 2.[prog] Inv 3.- Si vale Inv && !cond, entonces vale S2 4.- Existe una cota para la validez de cond Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } S1={x==1 && y==0} while (x < 11) {y = y + x;x=x+1;} S2={x==11 && y==55} ¿Y el invariante? Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } S1={x==1 && y==0} while (x < 11) {y = y + x;x=x+1;} S2={x==11 && y==55} ¿Y el invariante? Ya lo vimos pero tratemos de deducir qué necesitamos para llegar a S2 desde S1. Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } S1={x==1 && y==0} while (x < 11) {y = y + x;x=x+1;} S2={x==11 && y==55} ¿Y el invariante? Ya lo vimos pero tratemos de deducir qué necesitamos para llegar a S2 desde S1. •Sabemos que siempre que el ciclo ejecute x<=11 (1) •y es la suma entre 1 y x Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } 1.- Si vale S1, entonces vale Inv S1={x==1 && y==0}, Inv: x<=11 && y es la suma entre 1 y x (no inclusive) Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } 1.- Si vale S1, entonces vale Inv S1={x==1 && y==0}, Inv: x<=11 && y es la suma entre 1 y x (no inclusive) •Es trivial ver que x==1 implica x<=11. •Luego, si x==1, entonces la suma de los números entre 1 y 1 (no inclusive) da como resultado 0, y considerando que S1 afirma y==0, implicamos trivialmente que y==0. Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } Inv && cond 2.[prog] Inv Inv: x<=11 && y es la suma entre 1 y x (no inclusive), cond: x<11 Esto lo saben hacer, asi que les queda como tarea ;-) Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } 3.- Si vale Inv && !cond, entonces vale S2 Inv: x<=11 && y es la suma entre 1 y x (no inclusive), !cond: x>=11 S2={x==11 && y==55} Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } 3.- Si vale Inv && !cond, entonces vale S2 Inv: x<=11 && y es la suma entre 1 y x (no inclusive), !cond: x>=11 S2={x==11 && y==55} Si vale Inv y !cond, entonces vale {x<=11 && y es la suma entre 1 y x (no inclusive) && x>=11}, que es equivalente a {x==11 && y es la suma entre 1 y x (no inclusive)}. Luego, reemplazando en la expresión de y, se tiene que {x==11 && y=1+2+...+10}, que es equivalente a {x==11 && y==55} Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } 4.- Existe una cota para la validez de cond Corrección (Ejemplos) Repetición: while ([expr1][comp][expr2]) { [prog] } 4.- Existe una cota para la validez de cond Como mencionamos anteriormente en el ejemplo, se puede ver que la función f(x)=11-x decrece en cada iteración del ciclo por efecto de la asignación x=x+1 de forma que en algún momento f(x) queda acotada por 0, precisamente cuando x==11, en la última iteración. Resumen • Ufffffffffffffffffff... corrección para: - Ciclos