UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO CURSO: CIÊNCIA DA COMPUTAÇÃO TEORIA DA COMPUTAÇÃO Aula 04 – Programa Recursivo e Máquinas Prof.ª Danielle Casillo Funções recursivas Alguma função é recursiva quando é definida em termos dela própria. Teoria da Computação 2 Recursão - definição Uma definição na qual o item que está sendo definido aparece como parte da definição; O que devo ter? ◦ Uma Base ⇒ Ponto de Partida ◦ Um Passo Recursivo ⇒ Gerar novos casos Conceito poderoso ◦ Define conjuntos infinitos com comandos finitos Teoria da Computação 3 Recursão - definição Vantagens ◦ Redução do tamanho do código fonte ◦ Permite descrever algoritmos de forma mais clara e concisa Desvantagens ◦ Redução do desempenho de execução devido ao tempo para gerenciamento de chamadas ◦ Dificuldades na depuração de programas recursivos, especialmente se a recursão for muito profunda Teoria da Computação 4 Recursão - definição Uma sub-rotina recursiva pode ser: ◦ Diretamente recursiva: P chama P; ◦ Indiretamente recursiva P chama Q chama R.... chama P. Teoria da Computação 5 Passos para desenvolvimento de algoritmos recursivos Passo 1: Entender o problema. Exemplo: Série de Fibonacci 1, 1, 2, 3, 5, 8, 13, 21, 34, 55... Teoria da Computação 6 Passos para desenvolvimento de algoritmos recursivos Passo 2: Formular o problema em uma (ou mais) funções/procedimentos recursivos. ◦ ◦ ◦ ◦ ◦ Fibonacci(1) Fibonacci(2) Fibonacci(3) Fibonacci(4) Fibonacci(5) = = = = = 1 1 2 3 5 Qual é a sequência (equação matemática)? ◦ Fibonacci(1) = 1 ◦ Fibonacci(2) = 1 ◦ Fibonacci(n) = Fibonacci(n -1) + Fibonacci(n - 2) Teoria da Computação 7 Passos para desenvolvimento de algoritmos recursivos Passo 3: Implementar: Teoria da Computação 8 Passos para desenvolvimento de algoritmos recursivos Passo 4: Testar: ◦ A primeira coisa a fazer é verificar se o algoritmo sempre chegará ao caso trivial (fim do programa). Depois disso execute um teste montando a árvore de recursividade para alguns casos. Teoria da Computação 9 Recursividade Quando elaboramos uma rotina para efetuar uma tarefa, as possíveis soluções podem estar em uma entre duas classes: a) Solução Iterativa: na forma de uma rotina “fechada”, que especifica a rotina como uma sequência de passos onde o problema original não aparece. Por exemplo, o fatorial de n é: fat(n) = n * (n-1) * (n-2) * ... * 1 Teoria da Computação 10 Recursividade b) Solução Recursiva: a solução é expressa em uma forma “aberta”, onde a solução depende da solução do mesmo problema para um caso mais simples ou reduzido. Assim, podemos expressar a mesma função fat(n) do exemplo anterior como: fat(n) = n * fat(n-1) Teoria da Computação 11 Implementação de Fatorial Recursivo X Não Recursivo Implementação não Recursiva Function Fatorial (n: integer): real; var i : integer; result: real; begin result :=1; for i:= 2 to n do result := result * i; Fatorial:= result; end; Implementação Recursiva Function Fatorial (n: integer): real; begin If n = 0 then Fatorial := 1; else Fatorial := n * Fatorial (n-1); end; Teoria da Computação 12 Idéia básica Como já citado, a recursão corresponde a uma função “chamar” a si mesma, dentro de seu código; A execução de uma recursão cria uma árvore em que cada nó, que não seja nó folha, tenha um número N de filhos, sendo N o número de vezes que a função chama a si mesma dentro de seu código; Os nós folhas geralmente representam o final da recursão naquele trajeto e constituem o que chamamos de “caso de parada”. Teoria da Computação 13 Dicas Não se aprende recursividade sem praticar Para montar um algoritmo recursivo ◦ Defina pelo menos um caso básico (condição de terminação); ◦ Quebre o problema em problemas menores, definindo o(s) caso(s) com recursão(ões) ◦ Fazer o teste de finitude, isto é, certificar-se de que as sucessivas chamadas recursivas levam obrigatoriamente, e numa quantidade finita de vezes, ao(s) caso(s) básico(s) Teoria da Computação 14 Programa Recursivo Eu sou você amanhã, digo, uma recursão adiante Recursão é uma forma indutiva de definir programas. Sub-rotinas permitem a estruturação hierárquica de programas, possibilitando níveis diferenciados de abstração. Conjunto de Identificadores de Sub-Rotinas - R1, R2, .. Teoria da Computação - Aula 04 15 Programa Recursivo Expressões de sub-rotinas: ◦ A operação vazia sub-rotinas. constitui uma expressão de ◦ Cada identificador de operação constitui uma expressão de sub-rotinas. Teoria da Computação - Aula 04 16 Programa Recursivo ◦ A Composição Sequencial: é denotada por: D1;D2 resulta em uma expressão de sub-rotina cujo efeito é a execução de D1 e, após, a execução de D2. ◦ A Composição Condicional: Se D1 e D2 são expressões de sub-rotinas e T é um identificador de teste, então a composição condicional é denotada por: (se T então D1 senão D2) Teoria da Computação - Aula 04 17 Programa Recursivo Um Programa Recursivo P tem a seguinte forma: P é E0 onde R1 def E1, R2 def E2, ..., Rn def En em que (suponha k ∈ {1, 2, ..., n}): ◦ E0 : expressão inicial a qual é uma expressão de sub-rotinas; ◦ Ek : expressão que define a sub-rotina identificada por Rk. ◦ A operação vazia constitui um programa recursivo que não faz coisa alguma. Teoria da Computação - Aula 04 18 Programa Recursivo Exemplo: programa recursivo P é R; S onde R def F; (se T então R senão G; S), S def (se T então senão F; R) Note que a recursão é implícita, no sentido em que as subrotinas R e S se referenciam mutuamente, e portanto, R e S se autoreferenciam indiretamente. Teoria da Computação - Aula 04 19 Programa Recursivo A computação de um programa recursivo consiste na avaliação da expressão inicial onde cada identificador de sub-rotina referenciado é substituído pela correspondente expressão que o define, e assim sucessivamente, até que seja substituído pela expressão vazia , determinando o fim da recursão. Teoria da Computação - Aula 04 20 Programa Recursivo Até agora, foram definidos três tipos de programas. Entretanto, esses programas são incapazes de descrever uma computação, pois não se tem a natureza das operações ou dos testes, mas apenas um conjunto de identificadores. A natureza das operações e testes é especificada na definição de máquina. Teoria da Computação - Aula 04 21 Exercícios 1. Identifique e compare construções análogas às usadas nas definições de programas monolítico, iterativo e recursivo na linguagem de programação C++. Programa monolítico, Programa Iterativo, Programa Recursivo if A > 0 then { A = A – 1; B = B + 1; } while A > 0 do { A = A – 1; B = B + 1; } function TC { if A > 0 then { A = A – 1; B = B + 1; TC; } } Teoria da Computação - Aula 04 22 Exercícios 2. Fatorial para um programa recursivo: function fatorial (int n) { if (n == 0) return 1; else return n * fatorial (n - 1); } 3) Faça o mesmo programa para um programa iterativo Teoria da Computação - Aula 04 23 Exercícios int n; { long f = 1; int i; if (n == 0) return f; else { for (i = 1; i <= n; i++) f = f * i; return f; } } Teoria da Computação - Aula 04 24 Máquinas Interpreta os programas de acordo com os dados fornecidos. É capaz de interpretar um programa desde que possua uma interpretação para cada operação ou teste que constitui o programa. Teoria da Computação - Aula 04 25 Máquinas: definição A máquina deve suprir todas as informações necessárias para que a computação de um programa possa ser descrita: Caractrerísticas: ◦ cada identificador de operação deve caracterizar uma transformação na estrutura da memória da máquina; ◦ cada identificador de teste interpretado pela máquina deve ser associado a uma função verdade; Teoria da Computação - Aula 04 26 Máquinas Características: ◦ nem todo identificador de operação ou teste é definido em uma máquina; ◦ para cada identificador de operação ou teste definido em uma máquina, existe somente uma função associada; ◦ deve descrever o armazenamento ou a recuperação de informações na estrutura de memória. Teoria da Computação - Aula 04 27 Máquina: definição Uma Máquina é uma 7-upla M = (V, X, Y, πX, πY, ПF, ПT) ◦ ◦ ◦ ◦ ◦ ◦ ◦ V X Y πX πY ПF ПT conjunto de valores de memória; conjunto de valores de entrada; conjunto de valores de saída; função de entrada tal que: πX: X → V função de saída tal que: πY : V → Y conjunto de interpretações de operações; conjunto de interpretações de testes; Teoria da Computação - Aula 04 28 Máquina: definição Em que: ◦ ПF conjunto de interpretações de operações tal que, para cada identificador de operação F interpretado por M, existe uma única função: πF: V → V em ПF ◦ ПT conjunto de interpretações de testes tal que, para cada identificador de teste T interpretado por M, existe uma única função: πT: V → {verdadeiro, falso} em ПT Teoria da Computação - Aula 04 29 Máquina: Representação Gráfica M = (V , X, Y, πx, πy, ПF, ПT) X; (πx) V ΠF , ΠT Y; (πY) Teoria da Computação - Aula 04 30 Máquina: exemplo Máquina de dois registradores: Suponha uma especificação de uma máquina com dois registradores a e b os quais assumem valores em N (conjunto dos números naturais), com duas operações e um teste: ◦ ◦ ◦ ◦ subtração de 1 em a, se a > 0; adição de 1 em b; teste se a é zero. Os valores de entrada são armazenados em a (zerando b) e a saída retorna o valor de b. Teoria da Computação - Aula 04 31 Máquina: exemplo Dois_reg = (N2, N, N, armazena_a, retorna_b, {subtrai_a, adiciona_b}, {a_zero}) N2, N, N - Conjuntos de Memória, Entrada e Saída armazena_a (n) = (n, 0) retorna_b (n, m) = m subtrai_a (n, m) = (n-1, m) se n ≠ 0 e (0, m) se n = 0 adiciona_b (n, m) = (n, m+1) a_zero (n, m) = verdadeiro se n = 0 e falso se n ≠ 0 obs: dois registradores com valores em N podem ser definidos pelo produto cartesiano N2 onde os registradores a e b são representados pela primeira e segunda componente. Teoria da Computação - Aula 04 32 Programa para uma máquina Sejam M = (V, X, Y, πX, πY , ПF , ПT) uma máquina e P um programa onde PF e PT são os conjuntos de identificadores de operações e de testes de P, respectivamente. P é um programa para a máquina M se, e somente, se: ◦ para qualquer F ∈ PF, existe uma única função →V em ПF; πF: V→ ◦ para qualquer T ∈ PT, existe uma única função → {verdadeiro, falso} em ПT. πT: V→ Teoria da Computação - Aula 04 33 Programa para a máquina dois_reg Programa iterativo para a máquina de dois registradores: ◦ Programa Iterativo itv_b← ←a até a_zero faça (subtrai_a; adiciona_b) Teoria da Computação - Aula 04 34 Programa para a máquina dois_reg Programa recursivo para a máquina de dois registradores: ◦ Programa Recursivo rec_b← ←a rec_b ← a é R onde R def (se a_zero então senão S; R), S def subtrai_a; adiciona_b Teoria da Computação - Aula 04 35