Demostración de correctitud y terminación de ciclos

Slides:



Advertisements
Presentaciones similares
Capítulo 2 Algoritmos.
Advertisements

MANUAL EXPRESS DE C J.M.sevilla.
Iteración La iteración permite modelar problemas en los cuales una secuencia de instrucciones debe ejecutarse varias veces. La cantidad de iteraciones.
Seminario de Actualización - Excel Avanzado y Macros
Estructuras de Control
INFORMATICA I Funciones CLASE 13.
Estructuras de control
ESTRUCTURAS DE SECUENCIA
Programación en Matlab
Estructura de Datos y Algoritmos
Capítulo 1 “Elementos de Programación”
Microsoft© Visual Basic . Net.
COMPUTACION 2009 C lase 4 Programa PASCAL SENTENCIAS DATOS Expresiones Tipos Declaración de variables Declaración de variables Asignación Entrada/Salida.
Computación I Primer Semestre 2006 Capítulo IV Ciclos y Colecciones (con un sabor a algoritmos)
Clase # 2 de Matlab Presentado por: Oscar Danilo Montoya Giraldo Sistemas de Transmisión de Energía Universidad Tecnológica de Pereira Septiembre de 2014.
Programación de Sistemas
1. Desarrollo de Programas iterativos usando invariante
Estructuras de Control.
Estructuras de Repetición (Hacer-Mientras)
Tema ‧ Comando - while Repeticiones. Comando while ‧ Un ciclo es cualquier construcción de programa que repite una sentencia ó secuencia de sentencias.
1er Cuatrimestre 2008Algoritmos y Estructura de Datos 1 1 Más Invariante Ejercicios tomados del recuperatorio del parcial de imperativo del 2do cuatrimestre.
Sesión 13: Python (4) – Estructura Repetición. 2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática.
INTRODUCCIÓN AL LENGUAJE C++. Instrucciones Temas.
Algoritmo.
L ENGUAJE DE E SPECIFICACIÓN Algoritmos y Estructuras de Datos I Especificación – Práctica 4 AEDI Especificación – Práctica 4 1.
L ENGUAJE DE E SPECIFICACIÓN Algoritmos y Estructuras de Datos I Especificación – Práctica 2 AEDI Especificación – Práctica 2 1.
ESTRUCTURA DE CONTROL REPETITIVAS: WHILE, DO… WHILE
INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS Arreglo.
Prof. Jonathan Silva Ingeniería Civil – Informática I Ingeniería Civil Informática I Clase 5.
Ciclos condicionales y exactos Estructura de control de ciclos
Una vez observado el producto programado que se debe construir, es importante que realice los siguientes ejercicios con la ayuda del docente. 1)Con la.
TEMA 5: PROBABILIDAD. Índice Experimentos aleatorios. Sucesos. Tipos de sucesos. Sucesos elementales Suceso seguro Suceso imposible Álgebra de sucesos.
Estructuras de Datos ● Introducción y Heaps ● Docentes: ● Eugenia Simich ● Juan Manuel Rabasedas ● Sergio Giro.
MATEMÁTICAS II Tema 3 Determinantes. Determinantes. Determinantes de orden dos y de orden tres. Propiedades de los determinantes. Cálculo del valor de.
El Lenguaje Algebraico Si a un número entero le sumamos su doble, divides el resultado por 3 y, finalmente, multiplicas todo por 2, ¿qué número obtienes?.
Funciones Polinomicas
Funciones.
SUMATORIAS DEFINICION Sean a k y a n + 1 números reales y k y n números enteros positivos ( k  n ), entonces:
LA DEMOSTRACIÓN EN MATEMÁTICAS
Formas de Desisión Operadores lógicos II.
Ciclos condicionales y exactos Estructura de control de ciclos
El conjunto de los números naturales
La integral definida VBV.
1) Asociativa sobre (+):  (a + b) + c = a +(b + c) 
Estructuras de Control en Visual Basic.net
Estructuras de Datos Recursividad.
LEY DE SENOS.
LÍMITE DE UNA FUNCIÓN.
Ecuación vectorial de la recta en el plano y su ecuación cartesiana
Introducción a la Física Newtoniana
LÍMITE DE UNA FUNCIÓN.
Estructuras Estructuras En la creación de soluciones para algunos problemas surge la necesidad de agrupar datos de diferente tipo o de manejar datos que.
Fundamentos de Programación. Estructuras de Control
ESTRUCTURAS DE CONTROL EN VISUAL BASIC.NET Prof.: Rafael Mourglia.
Programación Lógica.
Estructuras de Repetición Pseudocodigo1 Estructuras de Repetición Algoritmos Mientras Hacer-Mientras Para.
Fundamentos de programación
Fórmulas Recursivas y Aproximaciones
DEL MANIPULADOR: PARTE 1 Roger Miranda Colorado
ECUACIONES CUADRATICAS Y RAICES DE ECUACIONES CUADRATICAS
Ecuaciones Lineales Dra. Noemí L. Ruiz © Derechos Reservados
Recursividad 1 Análisis de algoritmos. Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más.
Estructuras de Repetición Algoritmos
Ejemplo 1: Sea la sucesión de enteros b 0, b 1, b 2, b 3, b 4, b 5, ……. donde b n = 2n para todo N Entonces tenemos: b 0 = 2*0 = 0 b 1 = 2*1 = 1 b 2 =
ECUACIONES. HABILIDAD OBJETIVO Demostrar que comprenden la resolución de ejercicios de ecuaciones de una incógnita. TRAER PARA LA PROXIMA CLASE JUEGO.
LOGICA INTERACTIVA USO DEL HACER PARA Engloba un grupo de instrucciones HACER PARA [I] = 1 a 10 Es la única de las repetitivas que no depende de una expresion.
RELACIONES Y FUNCIONES. SUBCONJUNTO Sean A y B dos conjuntos. Al conjunto A se le llama un subconjunto de B si todo elemento de A es también elemento.
ALGORITMO DE ORDENAMIENTO POR BURBUJA. El método de la burbuja es uno de los mas simples, es tan fácil como comparar todos los elementos de una lista.
UNIDAD VI ARREGLO UNIDIMENSIONAL
Tema 9. Estructuras de repetición. Clase 2
Transcripción de la presentación:

Demostración de correctitud y terminación de ciclos 17 de octubre de 2014

Que vimos hasta ahora: Entre otras cosas vimos: Transición de estados Demostración de instrucciones “if” Teorema del Invariante Demostración de correctitud y terminación de ciclos

Agenda Otro ejemplo de demostración de correctitud y terminación de ciclos utilizando los cinco puntos del Teorema del Invariante: La precondición implica el invariante El cuerpo del ciclo preserva el invariante La postcondición vale al final La función variante es monótona decreciente El ciclo termina

Problema: filtrarMultiplos Dado un arreglo de enteros “a”, planteamos el problema de filtrar en “a” todos los elementos que son múltiplos de un número “m” dado, y pasar a otro arreglo “b” en las mismas posiciones todos los elementos de “a” que no son múltiplos de “m”, y adicionalmente obtener la suma de los elementos que quedaron en “a”. Ejemplo: 3 1 7 6 pre(a): m: 3 3 6 a: 1 7 b: suma: 3 3 6 = 12

Especificación: filtrarMultiplos Problema filtrarMultiplos (a:[ℤ], b:[ℤ], n : ℤ, m : ℤ, suma : ℤ) { requiere n == |a| == |b| ; requiere m > 0 ; requiere ∀(x ← a) x > 0 ; modifica a, b, suma ; asegura a == [if x mod m==0 then x else 0 | x ← pre(a)] ; asegura b == [if x mod m==0 then 0 else x | x ← pre(a)] ; asegura suma == ∑ [x | x ← pre(a), x mod m == 0] ;

Implementación: filtrarMultiplos void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ suma = 0; int i = 0; while (i < n) { if (a[i] % m == 0) { suma = suma + a[i]; b[i] = 0; } else { b[i] = a[i]; a[i] = 0; } i++;

Puntos a Demostrar Definimos: Demostramos la correctitud del ciclo: Estados: Ei Predicados: P, Pc, Pif, Qif, Qc, Q Invariante: I Guarda: B Función Variante: v Cota: c Demostramos la correctitud del ciclo: La precondición implica el invariante: Pc  I El cuerpo del ciclo preserva el invariante: {I ^ B} cuerpo {I} La postcondición vale al final: I ^ ¬B  Qc La función variante es monótona decreciente El ciclo termina: (I ^ v ≤ c)  ¬B

Transición de Estados void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: // estado Einicial; suma = 0; int i = 0; // Pc: // estado E0; while (i < n) { // I: // B: // v: , c: // estado E1; // vale I & B // Pif: if (a[i] % m == 0) { suma = suma + a[i]; b[i] = 0; } else { b[i] = a[i]; a[i] = 0; } // Qif: // estado E2; // vale Qif i++; // estado E3; // Qc: // estado E4; // vale Qc // Q:

Predicados void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: n == |a| == |b| && m > 0 && (paratodo x <- a) x > 0 && // a==pre(a) && b==pre(b) && suma=pre(suma) // estado Einicial; suma = 0 int i = 0;

Predicados void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: n == |a| == |b| && m > 0 && (paratodo x <- a) x > 0 && // a==pre(a) && b==pre(b) && suma=pre(suma) // estado Einicial; suma = 0 int i = 0; // implica Pc: suma==0 && i==0 && a==pre(a) && n==|a|==|b| && m>0

Predicados void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: n == |a| == |b| && m > 0 && (paratodo x <- a) x > 0 && // a==pre(a) && b==pre(b) && suma=pre(suma) // estado Einicial; suma = 0 int i = 0; // implica Pc: suma==0 && i==0 && a==pre(a) && n==|a|==|b| && m>0 // estado E0; while (i < n) { // I: (0 <= i <= n) // && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then // a[k]==pre(a)[k] && b[k]==0 else b[k]==pre(a)[k] && a[k]==0 // && (paratodo k<-[i..n)) a[k]==pre(a)[k] // && suma==sum(a[0..i)) // && n == |a| == |pre(a)| if (a[i] % m == 0) { suma = suma + a[i]; b[i] = 0; } else { b[i] = a[i]; a[i] = 0; }

Predicados void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: n == |a| == |b| && m > 0 && (paratodo x <- a) x > 0 && // a==pre(a) && b==pre(b) && suma=pre(suma) // estado Einicial; suma = 0 int i = 0; // implica Pc: suma==0 && i==0 && a==pre(a) && n==|a|==|b| && m>0 // estado E0; while (i < n) { // I: (0 <= i <= n) // && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then // a[k]==pre(a)[k] && b[k]==0 else b[k]==pre(a)[k] && a[k]==0 // && (paratodo k<-[i..n)) a[k]==pre(a)[k] // && suma==sum(a[0..i)) // && n == |a| == |pre(a)| // B: i < n // v: n – i, c: 0 // estado E1; // vale I & B if ...

Predicados void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: n == |a| == |b| && m > 0 && (paratodo x <- a) x > 0 && // a==pre(a) && b==pre(b) && suma=pre(suma) // estado Einicial; suma = 0 int i = 0; // implica Pc: suma==0 && i==0 && a==pre(a) && n==|a|==|b| && m>0 // estado E0; while (i < n) { // I: (0 <= i <= n) // && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then // a[k]==pre(a)[k] && b[k]==0 else b[k]==pre(a)[k] && a[k]==0 // && (paratodo k<-[i..n)) a[k]==pre(a)[k] // && suma==sum(a[0..i)) // && n == |a| == |pre(a)| // B: i < n // v: n – i, c: 0 // estado E1; // vale I & B if ... i++ } // Qc: (paratodo k<-[0..n)) if (pre(a)[k] % m == 0) then // && suma==sum(a[0..n)) // estado E4; // vale Qc

Predicados asegura a == [if x mod m==0 then x else 0 | x ← pre(a)] ; void filtrarMultiplos (int a[], int b[], const int n, const int m, int &suma){ // P: n == |a| == |b| && m > 0 && (paratodo x <- a) x > 0 && // a==pre(a) && b==pre(b) && suma=pre(suma) // estado Einicial; suma = 0 int i = 0; // implica Pc: suma==0 && i==0 && a==pre(a) && n==|a|==|b| && m>0 // estado E0; while (i < n) { // I: (0 <= i <= n) // && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then // a[k]==pre(a)[k] && b[k]==0 else b[k]==pre(a)[k] && a[k]==0 // && (paratodo k<-[i..n)) a[k]==pre(a)[k] // && suma==sum(a[0..i)) // && n == |a| == |pre(a)| // B: i < n // v: n – i, c: 0 // estado E1; // vale I & B if ... i++ } // Qc: (paratodo k<-[0..n)) if (pre(a)[k] % m == 0) then // && suma==sum(a[0..n)) // estado E4; // vale Qc // Q: (paratodo k<-[0..n)) if (pre(a)[k] % m == 0) then a[k]==pre(a)[k] else a[k]==0 // && (paratodo k<-[0..n)) if (pre(a)[k] % m == 0) then b[k]==0 else b[k]==pre(a)[k] // && suma==sum([pre(a)[k] | k <- [0..n), pre(a)[k] % m == 0]) asegura a == [if x mod m==0 then x else 0 | x ← pre(a)] ; asegura b == [if x mod m==0 then 0 else x | x ← pre(a)] ; asegura suma == ∑ [x | x ← pre(a), x mod m == 0] ;

La precondición implica el invariante: Pc  I Precondición del ciclo Pc: suma==0 && i==0 && a==pre(a) && n==|a|==|b| && m>0 Invariante I: (0 <= i <= n) (1) && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then a[k]==pre(a)[k] && b[k]==0 (2) else b[k]==pre(a)[k] && a[k]==0 && (paratodo k<-[i..n)) a[k]==pre(a)[k] (3) && suma==sum(a[0..i)) (4) && n == |a| == |pre(a)| (5) Asumiendo que Pc se cumple, veamos que vale cada una de las partes de I. Como vale Pc: Como i==0 en Pc, entonces 0<=i. Además, como n==|a| en Pc, entonces n>=0 porque la longitud de un arreglo no puede ser negativa. Y como además i==0, implica i==0<=n, implica i<=n. Entonces (0 <= i <= n) es verdadero. Como i==0, paratodo ( k <- [0..i) ) se puede escribir paratodo ( k <- [0..0) ) que siempre es verdadero porque [0..0) es un intervalo vacío. Como i==0, paratodo ( k <- [i..n) ) a[k]==pre(a)[k] se puede escribir paratodo ( k <- [0..n) ) a[k]==pre(a)[k]. Luego como n==|a| y k está en rango de a, la expresión anterior se reduce a a==pre(a), que es verdadero por Pc. Como i==0, entonces suma==sum( a[0..i) ) se puede escribir como suma == sum( a[0..0) ) == sum( a[] ) == 0 que es verdadero por Pc. De Pc sabemos que n == |a| == |pre(a)|, entonces es verdadero. Y como demostramos que todas las partes son verdaderas, entonces implica I.

El cuerpo del ciclo preserva el invariante: {I ^ B} cuerpo {I} Invariante I: (0 <= i <= n) (1) && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then a[k]==pre(a)[k] && b[k]==0 (2) else b[k]==pre(a)[k] && a[k]==0 && (paratodo k<-[i..n)) a[k]==pre(a)[k] (3) && suma==sum(a[0..i)) (4) && n == |a| == |pre(a)| (5) Guarda B: i < n Asumiendo que en E1 vale I y vale B, hay que demostrar que en E3 también vale I. A continuación analizamos cada uno de los estados: E1, E2, E3. // estado E0; while (i < n) { // estado E1; if (a[i] % m == 0) { // estado Eif1; suma = suma + a[i]; // estado Eif2; b[i] = 0; // estado Eif3; } else { // estado Eelse1; b[i] = a[i]; // estado Eelse2; a[i] = 0; // estado Eelse3; } // estado E2; i++; // estado E3; // estado E4;

Estado E1: vale I && B // estado E0; while (i < n) { // estado E1; vale I ^ B; // por B, implica i < n; // implica (0 <= i < n) (1) // && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) // then a[k]==pre(a)[k] && b[k]==0 (2) // else b[k]==pre(a)[k] && a[k]==0 // && (paratodo k<-[i..n)) a[k]==pre(a)[k] (3) // && suma==sum(a[0..i)) (4) // && n == |a| == |pre(a)| (5) // Pif: I ^ B if (a[i] % m == 0) { // estado Eif1; suma = suma + a[i]; // estado Eif2; b[i] = 0; // estado Eif3; } else { // estado Eelse1; b[i] = a[i]; // estado Eelse2; a[i] = 0; // estado Eelse3; } …

Estado E2 while (i < n) { // Pif: I ^ B if (a[i] % m == 0) { suma = suma + a[i]; b[i] = 0; } else { b[i] = a[i]; a[i] = 0; } // Qif: i==i@E1 && // ( (paratodo k<-[0..i)) a[k]==a@E1[k] && b[k]==b@E1[k] ) && // ( (paratodo k<-(i..n)) a[k]==pre(a)[k] && b[k]==pre(b)[k] ) && // (pre(a)[i]%m==0 && a[i]==a@E1[i] && b[i]==0 && suma==suma@E1+a[i]) || // (pre(a)[i]%m!=0 && b[i]==a@E1[i] && a[i]==0 && suma==suma@E1) && // n==|a|==|b| // estado E2; vale Qif; // implica (0 <= i < n) // && (paratodo k<-[0..i]) if (pre(a)[k] % m == 0) // then a[k]==pre(a)[k] && b[k]==0 // else b[k]==pre(a)[k] && a[k]==0 // && (paratodo k<-(i..n)) a[k]==pre(a)[k] // && suma==sum(a[0..i]) // && n == |a| == |pre(a)| i++; De los “vale” del estado E2, queremos llegar a alguna expresión que nos acerque a nuestra definición del invariante. Por ejemplo, como vale Qif y en Qif vale i==i@E1, podemos derivar la expresión (2). Ver documento pdf con el detalle de los pasos realizados). (1) (2)

Estado E3 Por lo tanto queda demostrado que se preserva el invariante. while (i < n) { if (a[i] % m == 0) { suma = suma + a[i]; b[i] = 0; } else { b[i] = a[i]; a[i] = 0; } i++; // estado E3; // vale i==i@E2 + 1 && // a=a@E2 && // b=b@E2 && // suma=suma@E2 En E3 vale i == i@E2 + 1, Entonces i@E2 == i – 1 En E3 vale a=a@E2, y en E3 vale b=b@E2, en E3 vale suma=suma@E2 Por expresión a la que llegamos en E2, reemplazando tenemos (0 <= i@E2 < n) && (paratodo k<-[0..i@E2]) if (pre(a)[k] % m == 0) then a@E2[k]==pre(a)[k] && b@E2[k]==0 else b@E2[k]==pre(a)[k] && a@E2[k]==0 && (paratodo k<-(i@E2..n)) a@E2[k]==pre(a)[k] && suma@E2==sum(a@E2[0..i@E2]) && n == |a| == |pre(a)| (4) Reemplazando (1) en (3) tenemos (0 <= i-1 < n) && (paratodo k<-[0..i-1]) if (pre(a)[k] % m == 0) && (paratodo k<-(i-1..n)) a@E2[k]==pre(a)[k] && suma@E2==sum(a@E2[0..i-1]) (5) Reemplazando (2) en (4) tenemos then a[k]==pre(a)[k] && b[k]==0 else b[k]==pre(a)[k] && a[k]==0 && (paratodo k<-(i-1..n)) a[k]==pre(a)[k] && suma==sum(a[0..i-1]) (6) Como último paso queda (0 <= i <= n) (por propiedad de Z) && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) (por propiedad de secuencias) && (paratodo k<-[i..n)) a[k]==pre(a)[k] (por propiedad de secuencias) && suma==sum(a[0..i)) (por propiedad de secuencias) Por lo tanto queda demostrado que se preserva el invariante.

La postcondición vale al final: I ^ ¬B  Qc Invariante I: (0 <= i <= n) (1) && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then a[k]==pre(a)[k] && b[k]==0 (2) else b[k]==pre(a)[k] && a[k]==0 && (paratodo k<-[i..n)) a[k]==pre(a)[k] (3) && suma==sum(a[0..i)) (4) && n == |a| == |pre(a)| (5) Negación de la Guarda B: i >= n Postcondición del ciclo Qc: (paratodo k<-[0..n)) then a[k]==pre(a)[k] && b[k]==0 && suma==sum(a[0..n)) && n == |a| == |pre(a)| Por (1) en la expresión del invariante y por la negación de la guarda tenemos: (0 <= i <= n) && (i>=n), entonces i==n. Reemplazando en la fórmula del invariante, queda: i==n && (paratodo k<-[0..n)) if (pre(a)[k] % m == 0) then a[k]==pre(a)[k] && b[k]==0 else b[k]==pre(a)[k] && a[k]==0 && (paratodo k<-[n..n)) a[k]==pre(a)[k] && suma==sum(a[0..n)) && n == |a| == |pre(a)| La sub expresión (paratodo k<-[n..n)) a[k]==pre(a)[k] se puede eliminar por ser lista vacía. Y por lo tanto llegamos a la expresión de Qc, que es lo que queríamos demostrar.

La función variante es monótona decreciente ¿Cuánto vale v==n-i en el estado E3? v@E3 == (n – i)@E3 == n – i@E3 porque n no se modifica. Por otro lado sabemos que: i@E3 == i@E2+1 y: i@E2 == i@E1 entonces: i@E3 == i@E1+1 Reemplazando: v@E3 == n – ( i@E1 + 1) == n – i@E1 – 1 == (n – i)@E1 – 1 == v@E1 – 1 < v@E1 Por lo tanto queda demostrado que v decrece. Función variante v: n-i, c:0 Estado E1 vale I ^ B Estado E3 vale i==i@E2 + 1 && a==a@E2 && b==b@E2 && suma==suma@E2

El ciclo termina: (I ^ v ≤ c)  ¬B Invariante I: (0 <= i <= n) (1) && (paratodo k<-[0..i)) if (pre(a)[k] % m == 0) then a[k]==pre(a)[k] && b[k]==0 (2) else b[k]==pre(a)[k] && a[k]==0 && (paratodo k<-[i..n)) a[k]==pre(a)[k] (3) && suma==sum(a[0..i)) (4) && n == |a| == |pre(a)| (5) Función variante v=n-i, c:0 (6) Negación de la Guarda B: i >= n Asumimos que vale I && v <=c Luego, como por (6) tenemos v: n-i y c:0 Reemplazando nos queda n-i <=0 que implica n <= I que es la negación de la guarda.

Conclusión Con estas demostraciones que cubren los cinco puntos del Teorema del Invariante podemos concluir que el ciclo es correcto según la especificación y termina. Queda como ejercicio la demostración de Pif  Qif y de P  Q Para más detalles ver el PDF complementario con la resolución.