Metodologia de Dijkstra para desenvolvimento de ciclos

Slides:



Advertisements
Apresentações semelhantes
UNIVERSIDADE FEDERAL DE UBERLÂNDIA ENGENHARIA CIVIL
Advertisements

Aula nº 1831/11/2006 Entrega e correcção do teste escrito.
Métodos, Parâmetros, Argumentos e Contratos
Engenharia de Software
Capitulo 6 Iterações.
1º Aviso Desconto no Interesse, Comportamento e Participação 2º Aviso Maior desconto no Interesse, Comportamento e Participação 3º Aviso Faz um teste com.
Análise e Síntese de Algoritmos
Programação para Engenharia I
Introdução a Programação
Introdução a Programação
Programação para Engenharia I
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2013
Flávio de Oliveira Alves
Prof. Msc. Raul Paradeda Aula 3 Fluxograma e Pseudocódigo
Modularização: funções e procedimentos
1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática.
Matrizes clássicas e vectores em C++
1 Aula 4 Ponteiros. 2003/2004 Programação Orientada para Objectos 2 Instâncias de um programa C++ int i = 10; Nome: i Tipo: int Valor: 10.
Aula 7 Instrução de iteração while. 2003/2004 Introdução à Programação 2 passo [G][G] [¬G][¬G] Início da actividade Fim da actividade Actividade Transição.
Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const.
Aula 10 Tipos Abstractos de Dados I. 2003/2004 Introdução à Programação 2 Flashback Lembram-se da Aula 4?
2002/2003 Programação Orientada para Objectos 1 Aula 11: Genericidade Genericidade usando herança Conceito de rotina genérica Conceito de classe genérica.
Modularização: funções e procedimentos (continuação)
1 Aula 3 Listas e iteradores (cont.). 2003/2004 Programação Orientada para Objectos 2 ListaDeInt : interface class ListaDeInt { public: typedef int Item;
Introdução à Programação
Aula 8 Polimorfismo.
Programação Baseada em Objectos Desenho de TAD
Aula 6 Instruções de selecção e instruções condicionais.
1 Aula 7 Herança. 2003/2004 Programação Orientada para Objectos 2 Conceitos fundamentais: Herança Polimorfismo Ligação dinâmica.
1 Aula 6 Classes que reservam recursos externos. 2003/2004 Programação Orientada para Objectos 2 PilhaDeInt : interface /** Representa pilhas de int.
Sobrecarga de nomes de rotinas Rotinas recursivas Invocação de rotinas
Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.
2002/2003 Programação Orientada para Objectos 1 Aula 5 Memória livre e instâncias dinâmicas Criação de instâncias dinâmicas Destruição de instâncias dinâmicas.
2002/2003 Programação Orientada para Objectos 1 Aula 4 Memória, unidade básica de memória e conceito de endereço Ponteiros Relação de ponteiros com matrizes.
2002/2003 Programação Orientada para Objectos 1 Aula 14 Tratamento de erros Origens dos erros Instruções usuais Papeis do humano Protecção contra: erros.
Construção de Algoritmos AULA 03
© 2003 Introdução à programaçãoComputadores e programação I Execução de instruções Aula nº4.
Estruturas de Repetição
© 2003 Introdução à programaçãoComputadores e programação I Linguagens de programação Introdução ao C (continuação)
PROGRAMAÇÃO I UNIDADE 4.
Operadores e Estruturas Condicionais 29/04/2014. Operadores Aritméticos.
Teoria da Computação Aula 5 Prof. Fabiano Sabha.
Introdução à Programação de Computadores
ALGORITMOS.
SOMA  0 fim início Simulação do algoritmo que soma os valores dos primeiros números naturais até o número fornecido como entrada: leia N T
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2014
INTRODUÇÃO.
2002/2003 Programação Orientada para Objectos 1 Aula 6 Classes que reservam recursos externos Problemas comuns Construtores e destrutores Construção por.
2002/2003 Programação Orientada para Objectos 1 Aula 2 Noção de lista e de iterador Operações com listas e iteradores Classes embutidas.
Comandos de Condição Aula 1 1. Introdução Até agora, todos os algoritmos que fizemos têm um fluxo de execução único. As instruções executadas são sempre.
Algoritmos Comandos de repetição.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2014 Capítulo VII Variáveis Indexadas Numéricas.
Estruturas de Controlo Repetitivas
FACULDADE DE CIÊNCIAS SOCIAIS E TECNOLÓGICAS Tecnologia em Redes de Computadores Algoritmos e linguagens de programação 1 (aula 06) Prof. Alessandro Bernardo.
Ciclos for, while e do...while
Aula Prática 2 Monitoria IP/CC (~if669).
Extensões no teste de escalonabilidade. André Luis Meneses Silva.
Modelação Aula T15 Modelação Conceptual de Sistemas Revisão do Comportamento OCL – Object Constraint Language José Borbinha.
Teste.
Informática e Computação Aula Estrutura de Repetição
Projeto de Desenvolvimento de Alimentos para Fins Especiais
Conteúdo da última aula 1 Ref. Bibliográfica - PMBOK Cap 1.
Teste.
Teste.
Teste.
Teste Teste contabil.
Teste\. testes.
Algoritmos e Estruturas de Dados I
ab LÓGICA DE PROGRAMAÇÃO ab
APRESENTAÇÃO. Teste 1 Teste 2 Teste 3.
Transcrição da apresentação:

Metodologia de Dijkstra para desenvolvimento de ciclos Aula 8 Metodologia de Dijkstra para desenvolvimento de ciclos

Introdução à Programação 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 Introdução à Programação 2003/2004

Introdução à Programação 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; Inicialização Acção potência *= x; Passo ++i; Progresso Introdução à Programação 2003/2004

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

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

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 Introdução à Programação 2003/2004

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

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

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

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; } Introdução à Programação 2003/2004

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

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

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; Introdução à Programação 2003/2004

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

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

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. Introdução à Programação 2003/2004

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; Introdução à Programação 2003/2004

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. Introdução à Programação 2003/2004

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; Introdução à Programação 2003/2004

Introdução à Programação raizInteiraDe() A  B  C  D 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 B A D A  C C Introdução à Programação 2003/2004

Introdução à Programação raizInteiraDe() CO: 0 ≤ r ≤ x1/2 < r + 1, ou seja 0 ≤ r  r2 ≤ x  x < (r + 1)2 . Começando a procurar em 0 (zero) e terminando quando se sabe que o valor seguinte já não serve… CI: 0 ≤ r  r2 ≤ x. ¬G: x < (r + 1)2. Introdução à Programação 2003/2004

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

Determinação da guarda Procurar guarda que leve ao resultado CI  ¬G  CO

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. Introdução à Programação 2003/2004

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; Introdução à Programação 2003/2004

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

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

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

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; Introdução à Programação 2003/2004

somaDosPrimeirosÍmpares() /** Devolve a soma dos primeiros n naturais ímpares. @pre 0 ≤ n. @post 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; Introdução à Programação 2003/2004

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

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

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

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; Introdução à Programação 2003/2004

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

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

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; } Falta um termo ao somatório. Introdução à Programação 2003/2004

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; Introdução à Programação 2003/2004

Introdução à Programação raizInteiraDe() // CI: 0 ≤ r  r2 ≤ x. while((r + 1)*(r + 1) <= x) { // CI  G: 0 ≤ r  r2 ≤ 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; } Não é necessária acção! Introdução à Programação 2003/2004

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

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

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 1 + 3 + 5 + 7 = * Introdução à Programação 2003/2004

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 1 + 3 + 5 + 7 = ** Introdução à Programação 2003/2004

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 1 + 3 + 5 + 7 = *** Introdução à Programação 2003/2004

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 1 + 3 + 4 + 7 = **** Introdução à Programação 2003/2004

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

Introdução à Programação 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? Introdução à Programação 2003/2004