Indução e Recursão Soluções dos exercícios propostos 1 Iremos demonstrar que a expressão proposta a seguir é correta: i = 0 + + + + + (n 1) = n(n 1), para n > 0 0 i<n OBS: Nas soluções do presente problema e dos problemas entre (a) e (d) usaremos E(m) para nos referirmos ao somatório à esquerda da igualdade, para n = m, e usaremos D(m) para nos referirmos à fórmula à direita da igualdade, aplicada igualmente sobre o argumento m [Passo Base] n = 1 (somatório contendo apenas o primeiro par) E(1) = (1 1) = 0 D(1) = 1(1 1) = 0 Assuma, por hipótese de indução, (HI), que E(m) = D(m), isto é, E(m) = 0 i<m i = m(m 1) = D(m), para um dado m > 1 Demonstraremos a seguir que E(m + 1) = D(m + 1) Observe que, por um lado: E(m + 1) = E(m) + ((m + 1) 1) = passo justificado pela (HI) = D(m) + m = m(m 1) + m = m(m 1 + ) = m(m + 1) Por outro lado, D(m + 1) = (m + 1)((m + 1) 1) = m(m + 1) Segue, por indução, que E(n) = D(n), para todo n (a) 0 + 1 + + + n = n(n + 1)(n + 1)/ E(0) = 0 = 0 D(0) = 0(0+1)( 0+1) = 0 Considere a hipótese de indução, (HI), segundo a qual: E(m) = D(m) para um dado m > 0 Demonstraremos a seguir que E(m + 1) = D(m + 1) Com efeito: E(m + 1) = E(m) + (m + 1) = D(m) + (m + 1) = passo justificado pela (HI) = m(m+1)(m+1) + (m + 1) = (m+1) (m(m + 1) + (m + 1)) = (m+1) (m + 7m + ) = (m+1)(m+)(m+) Ora, mas sabemos que D(m + 1) = (m+1)((m+1)+1)((m+1)+1) = (m+1)(m+)(m+) Segue, por indução, que E(n) = D(n), para todo n (b) 0 + 1 + + + n = n+1 1 E(0) = 0 = 1 D(0) = (0+1) 1 = 1 Lógica Aplicada à Computação 1
Considere a seguinte hipótese de indução, (HI): E(m) = D(m), para um dado m > 0 Verificaremos a seguir que, nestas condições, temos E(m + 1) = D(m + 1) De fato, por um lado temos que: E(m + 1) = E(m) + m+1 = D(m) + m+1 = passo justificado pela (HI) = m+1 1 + m+1 = m+1 1 = m+ 1 Por outro lado, temos que D(m + 1) = (m+1)+1 1 = m+ 1 Segue, por indução, que E(n) = D(n), para todo n (c) 0 + 1 + + + n = (n(n + 1)/) E(0) = 0 = 0 D(0) = ( 0(0+1) ) = 0 Assuma, por hipótese de indução, (HI), que E(m) = D(m) para um dado m > 0 Vamos demonstrar que E(m + 1) = D(m + 1) Com efeito: E(m + 1) = E(m) + (m + 1) = D(m) + (m + 1) = passo justificado pela (HI) = ( m(m+1) ) + (m + 1) = m (m+1) + (m + 1) = m (m+1) +(m+1) = (m+1) (m +(m+1)) = (m+1) (m +m+) = (m+1) (m+) = ( (m+1)(m+) ) Ora, o mesmo temos para D(m + 1), onde: D(m + 1) = ( (m+1)((m+1)+1) ) = ( (m+1)(m+) ) Segue, por indução, que E(n) = D(n), para todo n (d) 0 1 + 1 + + + n(n + 1) = n(n + 1)(n + )/ E(0) = 0(0 + 1) = 0 D(0) = 0(0+1)(0+) = 0 Considere a seguinte hipótese de indução, (HI): E(m) = D(m), para um dado m > 0 Iremos demonstrar que E(m + 1) = D(m + 1) Para E(m + 1) temos que: E(m + 1) = E(m) + (m + 1)(m + ) = passo justificado pela (HI) = D(m) + (m + 1)(m + ) = m(m+1)(m+) + (m + 1)(m + ) = m(m+1)(m+)+(m+1)(m+) = (m+1)(m+)(m+) Ora, para D(m + 1) temos que: D(m + 1) = (m+1)((m+1)+1)((m+1)+) = (m+1)(m+)(m+) Segue, por indução, que E(n) = D(n), para todo n Lógica Aplicada à Computação
(e) n + n é divisível por Observamos que 0 + 0 = 0, e 0 é divisível por Seja f(n) = n + n Por hipótese de indução, (HI), assumimos que f(m) é divisível por, para um certo m > 0 Demonstraremos que, nestas condições, o mesmo vale para f(m + 1), isto é, demonstraremos que (m + 1) + (m + 1) é divisível por Com efeito: (m + 1) + (m + 1) = m + m + 1 + m + 1 = m + m + m + = m + m + (m + 1) }{{}}{{} s 1 s Agora, quanto a s 1, note que m + m = f(m) é divisível por, pela (HI) Quanto a s, note que (m + 1) é igualmente divisível por Segue que s 1 + s = f(m + 1) é divisível por (f) n n é divisível por [Passo base] n = 0 Observamos que 0 0 = 0, e 0 é divisível por Assumindo a hipótese de indução, (HI), segundo a qual m m é divisível por para um certo m > 0, demonstraremos que o mesmo vale para m + 1, isto é, que (m + 1) (m + 1) é divisível por Com efeito: (m + 1) (m + 1) = m + m + m + 1 m 1 = m m + m + m = m m + (m + m) = Mas no exercício (e) vimos que m + m é divisível por, isto é, pode ser escrito na forma r, para algum r N, donde concluímos que: m m + r = m m }{{} + }{{} r s 1 s Agora, quanto a s 1, note que m m é suposto divisível por, pela (HI) Quanto a s, note que r é igualmente divisível por Segue que s 1 + s é divisível por (g) 9 n 8n 1 é divisível por [Passo base] n = 0 Observe que 9 0 8 0 1 = 0, e 0 é divisível por Assumimos a hipótese de indução, (HI), segundo a qual 9 m 8m 1 é divisível por, para um certo m > 0 Demonstraremos que o mesmo vale para m + 1, isto é, que 9 m+1 8(m + 1) 1 é divisível por Com efeito: 9 m+1 8(m + 1) 1 = 9 9 m 8m 8 1 = 9 9 m 9 8m = 9(9 m 1) 8m = (8 + 1)(9 m 1) 8m = 8(9 m 1) }{{} + (9m 1) 8m }{{} s 1 s Pela (HI) nós já assumimos que s = 9 m 8m 1 é divisível por Daí, para verificar que a Lógica Aplicada à Computação
expressão inteira é divisível por, só nos resta demonstrar também divide s 1 = 8(9 m 1), isto é, basta verificar que 9 m 1 é, por sua vez, divisível por 8 Faremos esta verificação no lema abaixo, procedendo novamente por indução Lema I Mostraremos que 9 n 1 é múltiplo de 8 Observamos que 9 0 1 = 0, e 0 é múltiplo de 8 Assuma por hipótese de indução, (HI), que esta propriedade vale para n = k Demonstraremos a seguir que ela vale igualmente para n = k + 1 Ora, por (HI), sabemos que 9 k 1 = 8s, para algum s > 0, donde 9 k = 8s + 1 Daí, temos: 9 k+1 1 = 9 9 k 1 = 9(8s + 1) 1 = 7s + 9 1 = 7s + 8 = 8(9s + 1) Obviamente, esta última expressão denota um múltiplo de 8 Segue, por indução, que 9 n 1 é múltiplo de 8, para todo n, concluindo o nosso lema Com a ajuda do Lema I, de volta à demonstração principal acabamos por verificar que s 1 é divisível por Daí, finalmente, concluímos que s 1 + s é divisível por Logo, por indução, segue que 9 n 8n 1 é de fato divisível por, para todo n (h) n + n 1 é divisível por 9 Observamos que 0 + 0 1 = 0, e 0 é divisível por 9 Assumimos agora a hipótese de indução, (HI), segundo a qual m +m 1 é divisível por 9, para um certo m > 0 Demonstraremos que o mesmo vale para m+1, isto é, que m+1 +(m+1) 1 é divisível por 9 Com efeito: m+1 + (m + 1) 1 = m + m + 1 = m + + m + m 1 = ( m + ) + ( m + m 1) = Na (HI) supusemos que m m 1 é divisível por 9 Para verificar que a expressão inteira é divisível por 9, só nos resta demonstrar então, o que faremos no lema abaixo, que m + é divisível por Lema II Mostraremos que n + é múltiplo de Observamos que 0 + =, e é múltiplo de Assumimos por hipótese de indução, (HI), que esta propriedade vale para n = k, e demonstraremos a seguir que neste caso ela valerá também para n = k + 1 Ora, k+1 + = k + = ( k ) + ( k + ) Como k é obviamente divisível por e, por (HI), k + é igualmente divisível por, a soma destas duas parcelas é divisível por Concluímos, por indução, que n + é múltiplo de, para todo n Com a ajuda do Lema II, de volta à demonstração principal concluímos finalmente a verificação, por indução, de que n + n 1 é de fato divisível por 9, para todo n Lógica Aplicada à Computação
O seguinte programa em Prolog expressa uma solução possível para o problema de selagem: /* 1 */ selar(8, 1, 1) /* */ selar(9,, 0) /* */ selar(10, 0, ) /* */ selar(custo, S, S5) :- Custo>10, CustoAnt is Custo -, /* 5 */ selar(custoant, SAnt, S5), S is SAnt + 1 O algoritmo subjacente a este programa informa como selar cartas com custo 8, 9 ou 10 centavos, e apresenta para valores mais elevados um procedimento recursivo guloso sobre os selos de centavos, isto é, um procedimento que usa tantos selos de centavos quanto possível Para qualquer custo n > 8 dado, a consulta selar(n,s,s5) retorna em S o número de selos de centavos e em S5 o número de selos de 5 centavos necessários para perfazer tal valor No entanto, apenas uma estratégia específica de selagem é implementada, e assim, embora uma consulta tal como selar(,, 1) seja bem sucedida, uma consulta tal como selar(, 1, ) falha, para a surpresa do leitor desavisado Se desejarmos que o predicado selar verifique se o custo n pode ser perfeito em termos de i selos de centavos e j selos de 5 centavos, basta estender o programa acima com a linha: selar(custo, S, S5) :- Custo>10, integer(s), integer(s5), Custo-(*S+5*S5) =:= 0 e então efetuar a consulta selar(n,i,j) Verificaremos a seguir, por indução matemática, que o algoritmo expresso acima é correto [Passo base] linhas 1, e Se o custo da carta a ser selada for de 8 centavos, use 1 selo de centavos e 1 selo de 5 centavos Se o custo for de 9 centavos, use selos de centavos Se o custo for de 10 centavos, use selos de 5 centavos [Passo indutivo] linhas e 5 Assumimos por hipótese de indução, (HI), que existe um valor k > 10 tal que toda carta com custo 8 i < k possa ser selada com selos de centavos e de 5 centavos Considere agora uma carta com custo k centavos Sele-a adicionando 1 selo de centavos à combinação usada para selar a carta com custo i = k Como, pela (HI), a carta com custo 8 k = i < k pode ser selada usando uma combinação de selos de e de 5 centavos, esta nova carta com custo k também pode ser selada da maneira sugerida, bastando usar um selo de centavos a mais Com o fito de ilustrar mais uma vez o procedimento definição recursiva + demonstração indutiva, considere agora um novo algoritmo para resolver o mesmo problema de selagem, mais uma vez expresso em Prolog: /* 1 */ selar(8, 1, 1) /* */ selar(10, 0, ) /* */ selar(11,, 1) /* */ selar(custo, S, 0) :- Custo>, Custo mod =:= 0, S is Custo// /* 5 */ selar(custo, S, S5) :- Custo>11, CustoAnt is Custo - 5, /* */ selar(custoant, S, S5Ant), S5 is S5Ant+1 O novo programa gera agora todas as possibilidades de selagem Para valores baixos, o procedimento é óbvio Para valores mais elevados, caso o custo seja um valor divisível por, a resposta do algoritmo é imediata: use tantos selos de quantos forem necessários Em caso contrário, pelo menos um selo de 5 deve ser empregado Cada nova consulta considera uma quantidade maior de selos de 5 para perfazer o mesmo custo O novo programa responde tanto a consultas do tipo Lógica Aplicada à Computação 5
selar(n,s,s5) (e fornece, uma a uma, todas as combinações possíveis para S e S5), quanto a consultas booleanas do tipo selar(n,i,j) Verifiquemos a seguir que este algoritmo é correto [Passo base] linhas 1,, e Se o custo da carta a ser selada for de 8 centavos, use 1 selo de centavos e 1 selo de 5 centavos Se o custo for de 10 centavos, use selos de 5 centavos Se o custo for de 11 centavos, use selos de centavos e 1 selo de 5 centavos Se o custo for um valor divisível por (por exemplo, 9 centavos, ou 1 centavos), use tantos selos de quantos forem necessários [Passo indutivo] linhas 5 e Assumimos por hipótese de indução, (HI), que existe um valor k > 1, não divisível por, tal que toda carta com custo 8 i < k possa ser selada com selos de centavos e de 5 centavos Considere agora uma carta com custo k centavos Como k não é divisível por, pelo menos uma de suas parcelas é um múltiplo de 5 Sele-a adicionando 1 selo de 5 centavos à combinação usada para selar a carta com custo i = k 5 Como, pela (HI), a carta com custo 8 k 5 = i < k pode ser selada usando uma combinação de selos de e de 5 centavos, esta nova carta com custo k também pode ser selada da maneira sugerida, bastando usar um selo de 5 centavos a mais Pode-se retornar em seguida ao passo base, em especial à linha do algoritmo, para buscar selar a carta com custo k 5 Outras soluções possíveis podem ser obtidas buscando compor o valor k usando cada vez mais selos de 5 centavos, atrasando a avaliação da regra na linha, mas reduzindo sempre o problema de selar uma carta com custo k ao problema de selar uma carta com custo inferior, e usando a (HI) (a) Faremos uma indução sobre #A, a cardinalidade do conjunto A [Passo Base] #A = 0, isto é, A = Observe que #P( ) = #{ } = 1 Tome um conjunto A tal que #A = k Assuma por hipótese de indução, (HI), que #P(A) = k Demonstraremos que, dado um conjunto B tal que #B = k + 1, devemos ter #P(B) = k+1 Com efeito, tome B = A {r}, onde r / A Logo, #B = #(A {r}) = #A + #{r} = k + 1 Note que o novo elemento, r / A, acrescenta a P(B) um novo elemento para cada subconjunto de A Com efeito, P(B) = P(A {r}) = P(A) {x {r} : x P(A)} Daí, #P(B) = #P(A) + #P(A) = #P(A) Pela (HI), podemos inferir que #P(B) = k = k+1, o que conclui o passo indutivo Segue, por indução, que #P(A) = (#A), para todo conjunto A finito (Uma demonstração semelhante pode ser feita para conjuntos transfinitos) (b) Fixaremos para esta demonstração um conjunto A com cardinalidade m e faremos uma indução sobre #B, a cardinalidade do conjunto B [Passo Base] #B = 0, isto é, B = Suponha que #(A B) 0, isto é, suponha que (A B) Assim, deve existir algum par a, b A B, onde b B [e a A] Impossível, pois B = Assuma por hipótese de indução, (HI), que se #B = k então #(A B) = m k Demonstraremos que, dado um conjunto C tal que #C = k + 1, devemos ter #(A C) = m (k + 1) Tome C = B {r}, onde r / B Logo, #C = #B + 1 O efeito sobre o produto cartesiano do acréscimo deste novo elemento, r / B, será o de acrescentar um novo par ordenado para cada elemento de A, isto é, A C = (A B) { a, r : a A}, donde #(A C) = #(A B) + #A = #(A B) + m Pela (HI), podemos inferir que #(A C) = m k + m = m (k + 1), o que conclui o passo indutivo Segue, por indução, que #(A B) = (#A) (#B), para quaisquer conjuntos A, B finitos Lógica Aplicada à Computação
5 A indução será feita sobre o número total de cumprimentos, cump, já realizados a cada determinado momento da festa [Passo Base] cump = 0 Ninguém cumprimentou ninguém Todos os convivas, neste momento, pertencem ao grupo P, donde #I = 0, um valor par Suponha por hipótese de indução, (HI), que a certa altura da festa, após k cumprimentos, temos #I = (i + 1), para algum i N (o caso #I = 0 já foi considerado no passo base) Após o próximo cumprimento teremos cump = k + 1 e os grupos P e I serão atualizados para P e I Queremos demonstrar que ainda assim teremos #I = j, para algum j N Três são as situações possíveis: (1) Dois convivas do grupo I acabaram de se cumprimentar Neste caso, ambos passam para o grupo P, e #I = #I Pela (HI), #I = (i + 1), donde #I = i () Dois convivas do grupo P acabaram de se cumprimentar Neste caso, ambos passam para o grupo I, e #I = #I + Pela (HI), #I = (i + 1), donde #I = (i + ) () Um conviva do grupo I acaba de cumprimentar um conviva do grupo P Neste caso, eles trocam de grupo, e #I = #I + 1 1 Pela (HI), #I = (i + 1), donde #I = (i + 1) Nas três situações temos #I par (a) Façamos uma tabela para os primeiros valores de n: n n n 0 1 0 1 1 8 9 1 1 5 5 A tabela sugere que a propriedade n > n vale a partir de n = 5 Verifiquemos se este é mesmo o caso: [Passo Base] n = 5 Observe que 5 = > 5 = 5 Assuma como hipótese de indução, (HI), que k > k, para um certo k > 5 Queremos demonstrar que, neste caso, temos k+1 > (k + 1) Considere as desigualdades a seguir: k+1 = k + k > k + k pela (HI) = k + k k > k + 5k pois k > 5 = k + k + k > k + k + 1 pois k > 5 = (k + 1) Lógica Aplicada à Computação 7
(b) Façamos uma tabela para os primeiros valores de n: n n n 0 1 0 1 1 8 8 7 9 51 79 10 10 1000 11 08 11 A tabela sugere que a propriedade n > n vale a partir de n = 10 Verifiquemos se este é mesmo o caso: [Passo Base] n = 10 Observe que 10 = 10 > 11 = 10 Assuma como hipótese de indução, (HI), que k > k, para um certo k > 10 Queremos demonstrar que, neste caso, temos k+1 > (k + 1) Considere as desigualdades a seguir: k+1 = k + k > k + k pela (HI) > k + 10k pois k > 10 = k + k + 7k > k + k + 70k pois k > 10 = k + k + k + 7k > k + k + k + 1 pois k > 10 = (k + 1) 7 Faremos uma indução sobre o número de regras de produção empregadas na formação de uma determinada expressão da gramática em questão Um bom teste prático para verificar se uma expressão E é propriamente balanceada consiste em tomar uma pilha vazia e ler a expressão E da esquerda para a direita; cada parêntese que abre é acrescentado à pilha, cada parêntese que fecha retira necessariamente da pilha um dos parênteses previamente acrescentados A expressão será propriamente balanceada se ao final da leitura tivermos novamente uma pilha vazia [Passo base] exatamente 1 regra foi empregada, em um único passo de formação A única expressão possível é a string vazia, que é evidentemente propriamente balanceada [Passo indutivo] Assuma, por hipótese de indução, (HI), que toda expressão produzida em até k passos de formação é propriamente balanceada, para um certo k > 0 Seja E uma expressão produzida em k + 1 passos Duas situações são possíveis: Caso 1: E é da forma (D), onde D é uma expressão produzida em k passos Pela (HI), D é propriamente balanceada O acréscimo de um parêntese que abre à esquerda de D e de um parêntese que fecha à direita de D obviamente mantém esta expressão propriamente balanceada Caso : E é da forma FG, onde F é uma expressão produzida em i passos e G é produzida em j passos, com i + j k Pela (HI), ambos F e G são propriamente balanceadas Obviamente, a concatenação linear de F e G produz uma expressão propriamente balanceada Fica para o leitor a tarefa de propor um procedimento que recebe uma expressão propriamente balanceada qualquer e mostrar como esta expressão pode ser gerada usando as regras de produção apresentadas (A demonstração de que tal procedimento é correto deve, mais uma vez, ser feita por indução) Lógica Aplicada à Computação 8