Aula 7 Instrução de iteração while Instrução while Início da actividade while(G) passo Transição Entroncamento Guarda Ramificação [¬G] [G] Actividade passo 2 Introdução à Programação Fim da actividade 2003/2004 potênciaDe() double potênciaDe(double const x, int const n) { int i = 1; double potência = x; while(i <= n) { potência *= x; ++i; } return potência; } 3 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência 2.0 3 1 2.0 i <= n while(i <= n) { potência *= x; ++i; } 4 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 while(i <= n) { potência *= x; ++i; } 5 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 4.0 while(i <= n) { potência *= x; ++i; } 6 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 while(i <= n) { potência *= x; ++i; } 7 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 while(i <= n) { potência *= x; ++i; } 8 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 8.0 while(i <= n) { potência *= x; ++i; } 9 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 3 8.0 while(i <= n) { potência *= x; ++i; } 10 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 3 8.0 V 2.0 3 while(i <= n) { potência *= x; ++i; } 11 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 3 8.0 V 2.0 3 16.0 while(i <= n) { potência *= x; ++i; } 12 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 3 8.0 V 2.0 3 4 16.0 while(i <= n) { potência *= x; ++i; } 13 Introdução à Programação 2003/2004 potênciaDe(2.0, 3) x n i potência i <= n 2.0 3 1 2.0 V 2.0 3 2 4.0 V 2.0 3 3 8.0 V 2.0 3 4 16.0 F Errado! A guarda i ≤ n está errada. 14 Introdução à Programação 2003/2004 potênciaDe() double potênciaDe(double const x, int const n) { int i = 1; double potência = x; while(i < n) { potência *= x; ++i; } return potência; } 15 Introdução à Programação 2003/2004 potênciaDe(5.0, 0) x n i potência 5.0 0 1 5.0 i < n while(i < n) { potência *= x; ++i; } 16 Introdução à Programação 2003/2004 potênciaDe(5.0, 0) x n i potência i < n 5.0 0 1 5.0 F Errado! A inicialização está errada. 17 Introdução à Programação 2003/2004 potênciaDe() double potênciaDe(double const x, int const n) { int i = 0; double potência = 1.0; while(i < n) { potência *= x; ++i; } return potência; } 18 Introdução à Programação 2003/2004 Estrutura de um ciclo inic (inicialização) while(G) passo inic Normalmente passo é [G] { acção prog (progresso) acção prog } 19 [¬G] Introdução à Programação 2003/2004 potênciaDe() E se alguém invoca potênciaDe(2.0, -1)? 20 potênciaDe() devolve erradamente 1.0 Porquê? Pré-condição; ou Implementação Introdução à Programação 2003/2004 potênciaDe() /** Devolve a potência n de x. @pre 0 ≤ n. @post potênciaDe = xn. */ double potênciaDe(double const x, int const n) { int i = 0; double potência = 1.0; while(i < n) { potência *= x; ++i; } return potência; } 21 Introdução à Programação 2003/2004 potênciaDe() /** Devolve a potência n de x. @pre 0 ≤ n. @post potênciaDe = xn. */ double potênciaDe(double const x, int const n) { int i = 0; double potência = 1.0; while(i != n) { potência *= x; ++i; } return potência; } 22 Introdução à Programação 2003/2004 potênciaDe() /** Devolve a potência n de x. @pre 0 ≤ n. @post potênciaDe = xn. */ double potênciaDe(double const x, int const n) { assert(0 <= n); int i = 0; double potência = 1.0; while(i != n) { potência *= x; ++i; } return potência; } 23 Introdução à Programação 2003/2004 A reter... 24 Programação com cinto, liga e suspensórios Escrever sempre a especificação da rotina Demonstrar que os ciclos estão correctos Introdução à Programação 2003/2004 potênciaDe() /** ... */ double potênciaDe(double const x, int const n) { assert(0 <= n); 1 int i = 0; double potência = 1.0; 2 while(i != n) { 3 potência *= x; ++i; 4 } 5 return potência; } 25 Introdução à Programação 2003/2004 Asserções nas transições {PC: 0 ≤ n} 1 int i = 0; double potência = 1.0; {0 ≤ n i = 0 potência = 1} 2 [i = n] {0 ≤ n 0 ≤ i < n potência = xi} 3 [i ≠ n] potência *= x; {0 ≤ n 0 < i ≤ n potência = xi} 26 5 {0 ≤ n i = n potência = xn} ++i; 4 Introdução à Programação 2003/2004 Condição Invariante Condição verdadeira 27 Depois de inicialização Antes do passo Depois do passo Depois do ciclo Condição correspondente à união dos conjuntos definidos pelas asserções 2, 3, 4 e 5 CI: 0 ≤ i ≤ n potência = xi. Introdução à Programação 2003/2004 Correcção parcial de um ciclo 1. Descobrir condição invariante (CI) 2. Provar que init estabelece veracidade de CI 3. Provar que CI G seguida de passo CI 4. Provar que CI ¬G CO 28 Introdução à Programação 2003/2004 init estabelece veracidade de CI init: int i = 0; double potência = 1.0; CI: 0 ≤ i ≤ n potência = xi. 0 ≤ 0 ≤ n 1.0 = x0. 0 ≤ n 1.0 = 1.0. VV V 29 Dada a PC, 0 ≤ n, é V. Introdução à Programação 2003/2004 CI G seguida de passo CI: demonstração directa while(i != n) { // CI G: 0 ≤ i ≤ n potência = xi i ≠ n // CI G: 0 ≤ i < n potência = xi potência *= x; // 0 ≤ i < n potência = xi x // 0 ≤ i < n potência = xi + 1 ++i; // 0 ≤ (i - 1) < n potência = x(i - 1) + 1 // 1 ≤ i < n + 1 potência = xi // // CI : 0 ≤ i ≤ n potência = xi } 30 Introdução à Programação 2003/2004 CI G seguida de passo CI: demonstração inversa while(i != n) { // CI G: 0 ≤ i ≤ n potência = xi i ≠ n // CI G: 0 ≤ i < n potência = xi Implica // 0 ≤ i + 1 ≤ n potência x = xi + 1 // -1 ≤ i ≤ n - 1 potência x = xi + 1 // -1 ≤ i < n potência x = xi + 1 potência *= x; // 0 ≤ i + 1 ≤ n potência = xi + 1 ++i; // CI: 0 ≤ i ≤ n potência = xi } 31 Introdução à Programação 2003/2004 CI ¬G CO CI: 0 ≤ i ≤ n potência = xi. G: i ≠ n. CI ¬G: 0 ≤ i ≤ n potência = xi i = n CI ¬G: 0 ≤ n ≤ n potência = xn i = n CI ¬G: 0 ≤ n potência = xn i = n CO: potência = xn 32 Introdução à Programação 2003/2004 E o ciclo termina sempre? 33 i começa em 0 (zero) Pré-condição: 0 ≤ n Guarda: i ≠ n Progresso: ++i Se 0 = n, 0 ≠ 0 é F e o ciclo não é executado Se 0 < n, como i começa em 0 e avança de 1 em 1, n é atingido ao fim de n iterações Introdução à Programação 2003/2004 A reter... PC das rotinas tão fraca quanto possível CO das rotinas tão fortes quanto possível Violação da PC dá origem a ciclo “infinito” que facilita detecção de erros ao produtor CI dos ciclos tão forte quanto possível 34 Bom para consumidor Complicado para produtor Guardas dos ciclos tão fracas quanto possível Bom para consumidor Complicado para produtor PC ideal: V Explica funcionamento do ciclo Introdução à Programação 2003/2004 Aula 7: Sumário Instrução while 35 Sintaxe Semântica Exemplo de ciclos simples Inicialização, guarda, passo (acção e progresso) Condição invariante Demonstração da correcção de ciclos Importância da fraqueza das guardas Introdução à Programação 2003/2004