A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Aula 8 Metodologia de Dijkstra para desenvolvimento de ciclos.

Apresentações semelhantes


Apresentação em tema: "Aula 8 Metodologia de Dijkstra para desenvolvimento de ciclos."— Transcrição da apresentação:

1 Aula 8 Metodologia de Dijkstra para desenvolvimento de ciclos

2 2003/2004 Introdução à Programação 2 Ciclos Parte importante da escrita de algoritmos Impossível demonstrar correcção com testes Condições invariantes importantes para demonstrar correcção Verdadeiras do início ao fim dos ciclos Fortes! Referem todas instâncias envolvidas

3 2003/2004 Introdução à Programação 3 potênciaDe() /** Devolve a potência n de 0 potênciaDe = x n. */ 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; } Inicialização Passo potência *= x; Acção ++i; Progresso

4 2003/2004 Introdução à Programação 4 Diagrama de actividade ++i; [ i n ] [ i = n ] int i = 0; double potência = 1.0; potência *= x; {PC: 0 n } {0 n i = 0 potência = 1} {0 n 0 i < n potência = x i } {0 n 0 < i n potência = x i } {0 n i = n potência = x n } inic prog acção passo

5 2003/2004 Introdução à Programação 5 Condição invariante CI: 0 i n potência = x i. Condição invariante explica funcionamento do ciclo Durante todo o ciclo potência contém x i, estando sempre i entre 0 e n Como i varia entre 0 e n, e termina com n, o objectivo é atingido

6 2003/2004 Introdução à Programação 6 Metodologia de Dijkstra Edsger Dijkstra Fundador da programação disciplinada Programação é uma ciência Metodologia Baseia-se na condição objectivo Programação é actividade orientada pelos objectivos Condição invariante retirada da condição objectivo

7 2003/2004 Introdução à Programação 7 Soma dos primeiros n ímpares inteiros int somaDosPrimeirosÍmpares(int const n) { int r = ? ;... return r; }

8 2003/2004 Introdução à Programação 8 Raiz inteira int raizInteiraDe(int const x) { int r = ? ;... return r; }

9 1Especificar o problema Escrever o Pré-condição o Condição objectivo

10 2003/2004 Introdução à Programação 10 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int r = ? ;... // CO: r = (S j : 0 j < n : 2j + 1). return r; }

11 2003/2004 Introdução à Programação 11 raizInteiraDe() /** Devolve a melhor aproximação por defeito de x 0 0 raizInteiraDe x 1/2 < raizInteiraDe + 1. */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = ? ;... // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

12 2Será necessário um ciclo? Verificar se ciclo é melhor abordagem o Análise do problema o Intuição! o Experiência…

13 2003/2004 Introdução à Programação 13 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int r = ? ; while(... ) {... } // CO: r = (S j : 0 j < n : 2j + 1). return r; }

14 2003/2004 Introdução à Programação 14 raizInteiraDe() /** Devolve a melhor aproximação por defeito de x 0 0 raizInteiraDe x 1/2 < raizInteiraDe + 1. */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = ? ; while(... ) {... } // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

15 3Obtenção da condição invariante Programar é actividade orientada pelos objectivos o Enfraquecer a CO para obter a CI

16 2003/2004 Introdução à Programação 16 somaDosPrimeirosÍmpares() Substituição de constante na CO por variável inic int i = ?; int r = ?; CO: r = (S j : 0 j < n : 2j + 1). r = (S j : 0 j < i : 2j + 1). CO: r = (S j : 0 j < i : 2j + 1) i = n. Não é equivalente a CO.

17 2003/2004 Introdução à Programação 17 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = ?; int r = ? ; while(... ) {... } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

18 2003/2004 Introdução à Programação 18 somaDosPrimeirosÍmpares() CO: r = (S j : 0 j < i : 2j + 1) i = n. Enfraquecendo as restrições relativas a i CI: r = (S j : 0 j < i : 2j + 1) ? i ?. CI: r = (S j : 0 j < i : 2j + 1) 0 i n.

19 2003/2004 Introdução à Programação 19 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = ?; int r = ? ; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(... ) {... } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

20 2003/2004 Introdução à Programação 20 raizInteiraDe() Factorização da condição objectivo Parte é negação da guarda Parte restante é condição invariante CO: A B C D CI: A C Sabendo que no final do ciclo se quer CI ¬G CO ¬G: B D Logo, CI ¬G = CO A B C D A B C D A C

21 2003/2004 Introdução à Programação 21 raizInteiraDe()

22 2003/2004 Introdução à Programação 22 raizInteiraDe() /** Devolve a melhor aproximação por defeito de x 0 0 raizInteiraDe x 1/2 < raizInteiraDe + 1. */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = ? ; // CI: 0 r r 2 x. while(... ) {... } // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

23 4Determinação da guarda Procurar guarda que leve ao resultado o CI ¬G CO

24 2003/2004 Introdução à Programação 24 somaDosPrimeirosÍmpares() CI ¬G: r = (S j : 0 j < i : 2j + 1) 0 i n ¬G. CO: r = (S j : 0 j < i : 2j + 1) i = n. Qual a guarda mais simples que garante a verificação da CO? ¬G: i = n. ou seja, G: i n. CI ¬G: r = (S j : 0 j < i : 2j + 1) 0 i n i = n. CI ¬G: r = (S j : 0 j < i : 2j + 1) 0 n i = n. que implica CO.

25 2003/2004 Introdução à Programação 25 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = ?; int r = ? ; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(i != n) {... } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

26 2003/2004 Introdução à Programação 26 raizInteiraDe() CO: 0 r r 2 x x < ( r + 1) 2. CI: 0 r r 2 x. Logo, sabendo que CI ¬G = CO ¬G: x < ( r + 1) 2 ou seja, G: ( r + 1) 2 x.

27 2003/2004 Introdução à Programação 27 raizInteiraDe() /** Devolve a melhor aproximação por defeito de x 0 0 raizInteiraDe x 1/2 < raizInteiraDe + 1. */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = ? ; // CI: 0 r r 2 x. while((r + 1) * (r + 1) <= x) {... } // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

28 5Determinação da inicialização Escolher inicialização tão simples quanto possível: o Sabendo que PC é verdadeira o Garantir verificação da CI

29 2003/2004 Introdução à Programação 29 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = ? ; int r = ? ; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(i != n) {... } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

30 2003/2004 Introdução à Programação 30 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = 0; int r = 0; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(i != n) {... } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

31 2003/2004 Introdução à Programação 31 raizInteiraDe() /** Devolve a melhor aproximação por defeito de x 0 0 raizInteiraDe x 1/2 < raizInteiraDe + 1. */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = ? ; // CI: 0 r r 2 x. while((r + 1)*(r + 1) <= x) {... } // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

32 2003/2004 Introdução à Programação 32 raizInteiraDe() /** Devolve a melhor aproximação por defeito de x 0 0 raizInteiraDe x 1/2 < raizInteiraDe + 1. */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = 0; // CI: 0 r r 2 x. while((r + 1)*(r + 1) <= x) {... } // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

33 6Escolha de um progresso Um ciclo tem de terminar o Num número finito de passos o Rapidamente? Pode valer a pena investigar progressos complexos

34 2003/2004 Introdução à Programação 34 somaDosPrimeirosÍmpares() /**... */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = 0; int r = 0; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(i != n) { acção ++i; } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

35 2003/2004 Introdução à Programação 35 raizInteiraDe() /**... */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = 0; // CI: 0 r r 2 x. while((r + 1)*(r + 1) <= x) { acção ++r; } // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

36 7Determinação da acção Escolher acção tal que // CI e G. acção prog // CI. Garante veracidade de CI apesar do progresso

37 2003/2004 Introdução à Programação 37 somaDosPrimeirosÍmpares() // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(i != n) { // CI G: r = (S j : 0 j < i : 2j + 1) 0 i n i n. // CI G: r = (S j : 0 j < i : 2j + 1) 0 i < n. acção // r = (S j : 0 j < i + 1 : 2j + 1) 0 i + 1 n. // r = (S j : 0 j < i + 1 : 2j + 1) -1 i < n. ++i; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. } Falta um termo ao somatório.

38 2003/2004 Introdução à Programação 38 somaDosPrimeirosÍmpares() /**... */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); // 0 n. int i = 0; int r = 0; // CI: r = (S j : 0 j < i : 2j + 1) 0 i n. while(i != n) { r += 2 * i + 1; ++i; } // CO: r = (S j : 0 j < i : 2j + 1) i = n. // que implica CO: r = (S j : 0 j < n : 2j + 1). return r; }

39 2003/2004 Introdução à Programação 39 raizInteiraDe() // CI: 0 r r 2 x. while((r + 1)*(r + 1) <= x) { // CI G: 0 r r 2 x ( r + 1) 2 x. // CI G: 0 r ( r + 1) 2 x. acção // 0 r + 1 ( r + 1) 2 x. // -1 r ( r + 1) 2 x. ++r; // CI: 0 r r 2 x. } Não é necessária acção!

40 2003/2004 Introdução à Programação 40 raizInteiraDe() /**... */ int raizInteiraDe(int const x) { assert(0 <= x); // 0 x. int r = 0; // CI: 0 r r 2 x. while((r + 1)*(r + 1) <= x) ++r; // CO: 0 r x 1/2 < r + 1. assert(0 <= r and r * r <= x and x < (r + 1) * (r + 1)); return r; }

41 8E se alguma coisa falhar? Voltar atrás acção ou inic demasiado complexas CI menos boa...

42 2003/2004 Introdução à Programação 42 Será que na soma dos ímpares o ciclo é necessário? Inteiros na base 1 1: * 2: ** 3: *** 4: **** 5: *****... Impares 1: * 3: * ** 5: * *** 7: * **** Soma dos primeiros 4 ímpares = *

43 2003/2004 Introdução à Programação 43 Será que na soma dos ímpares o ciclo é necessário? Inteiros na base 1 1: * 2: ** 3: *** 4: **** 5: *****... Impares 1: * 3: * ** 5: * *** 7: * **** Soma dos primeiros 4 ímpares = **

44 2003/2004 Introdução à Programação 44 Será que na soma dos ímpares o ciclo é necessário? Inteiros na base 1 1: * 2: ** 3: *** 4: **** 5: *****... Impares 1: * 3: * ** 5: * *** 7: * **** Soma dos primeiros 4 ímpares = ***

45 2003/2004 Introdução à Programação 45 Será que na soma dos ímpares o ciclo é necessário? Inteiros na base 1 1: * 2: ** 3: *** 4: **** 5: *****... Impares 1: * 3: * ** 5: * *** 7: * **** Soma dos primeiros 4 ímpares = ****

46 2003/2004 Introdução à Programação 46 somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais 0 somaDosPrimeirosÍmpares = (S j : 0 j < n : 2j + 1). */ int somaDosPrimeirosÍmpares(int const n) { assert(0 <= n); return n * n; }

47 2003/2004 Introdução à Programação 47 Aula 8: Sumário Importância da especificação do problema Noção de invariante de um ciclo Condição invariante, inicialização e guarda de um ciclo Metodologia de Dijkstra para desenvolvimento de ciclos: Obtenção da condição invariante Obtenção da guarda Inicialização Progresso Acção Importância da metodologia: Base formal para desenvolvimento Controlo dos erros Redução de surpresas Melhor raciocínio Maior eficiência Prática da construção de ciclos: usar ou não usar metodologia?


Carregar ppt "Aula 8 Metodologia de Dijkstra para desenvolvimento de ciclos."

Apresentações semelhantes


Anúncios Google