• Nenhum resultado encontrado

TC EAD Fasciculo3 sem edicao

N/A
N/A
Protected

Academic year: 2019

Share "TC EAD Fasciculo3 sem edicao"

Copied!
69
0
0

Texto

(1)

Fascículo 3

(2)

Capítulo 1 –

Autômatos com Pilha (APs)

No fascículo 1, vimos três tipos de autômatos aos quais nos referimos pelo nome geral pelo nome de autômatos finitos: AFD, AFND e ε-AFND. Apesar de

algumas diferenças de funcionamento, os três têm o mesmo poder de representação de linguagens, sendo as linguagens que eles representam chamadas de linguagens regulares.

Neste capítulo, veremos um modelo de autômato mais poderoso do que os três modelos de autômatos finitos – é o modelo Autômato de Pilha (AP). Este modelo é capaz de reconhecer a classe das linguagens livres de contexto, que inclui toda a classe das linguagens regulares e mais algumas outras. Você deve lembrar que nós já apresentamos a classe das linguagens livres de contexto no final do fascículo 2, quando definimos que esta é classe das

linguagens que podem ser representadas por meio de gramáticas livres de contexto.

Assim, o modelo autômato de pilha, que agora vamos apresentar, é um modelo que funciona de modo parecido com os autômatos finitos, mas que têm poder equivalente ao das gramáticas livres de contexto. Vamos começar o

estudo deste novo modelo apresentando seus princípios básicos de funcionamento na seção a seguir.

1.1 Princípio de Funcionamento

(3)

símbolos nessa pilha para ler mais tarde e isso dá ao autômato um poder adicional em relação aos ε-AFNDs.

Para explicar o nome “pilha”, pense no que é uma “pilha de pratos” (ou uma “pilha de livros”). Esse é o nome que damos a um conjunto de pratos dispostos um sobre o outro. Geralmente, se queremos colocar mais um prato na pilha, colocamos ele no topo, em cima dos outros pratos. Também quando vamos remover um prato, geralmente, tiramos aquele que está no topo. Como resultado, o prato que colocamos por último acaba sendo o primeiro a ser

retirado. De modo geral, em Computação, chamamos de pilha toda estrutura

que segue essa regra de inserção e remoção. A figura abaixo ilustra isso.

Os autômatos que vamos ver usam uma pilha para guardar símbolos especiais, que chamaremos símbolos da pilha. Os autômatos só podem inserir e remover esses símbolos de uma mesma extremidade da pilha (como se fosse o “topo” de uma pilha de pratos). Assim, o último símbolo que é escrito

fica na primeira posição. Outro detalhe é que a pilha dos APs não inicia vazia –

ela começa automaticamente com um símbolo de início pré-definido.

(4)

Como nos autômatos finitos, o símbolo lido em uma transição de um AP é automaticamente removido. Isso vale tanto para o próximo símbolo da cadeia como para o símbolo do topo da pilha. Além disso, depois das remoções, o autômato também insere na pilha uma cadeia de símbolos.

A representação gráfica de um AP é parecida com a dos outros autômatos vistos. O estado inicial e os estados de aceitação são representados da mesma maneira (reveja a apostila 1 caso não lembre). A grande diferença na representa gráfica são as setas de transição entre estados, que precisam conter toda a informação que apresentamos. Para isso, elas recebem rótulos no seguinte formato:

s, X / Y1...Yk , onde:

s é o símbolo que será lido da cadeia (ou ε para não ler nada)

X é o símbolo que será lido do topo da pilha (ou ε para não ler nada)

Y1...Yk é a cadeia de símbolos que será escrita na pilha (ou ε para não escrever nada), considerando que os símbolos serão empilhados na ordem inversa (de Yk para Y1), deixando Y1 no topo

Um detalhe importante é que, semelhante aos ε-AFNDs, podemos usar o símbolo especial ε para indicar que um AP pode fazer a transição sem ler nem remover nenhum símbolo da entrada (se for usado no lugar do rótulo s) ou da pilha (se for usado no lugar do X). Também podemos usar o ε para representar que, após uma transição, nenhum símbolo será inserido na pilha (se o colocarmos no lugar do rótulo Y1...Yk).

(5)

Veja que o autômato dado tem uma transição de q0 para q1 que só pode ser realizada se duas condições forem verdadeiras: o próximo símbolo da cadeia de entrada tem que ser “a” e o próximo símbolo da pilha tem que ser “$”. Quando ambas as condições forem verdadeiras no estado q0, o autômato muda para q1 e escreve os símbolos ABC na pilha na ordem inversa (deixando o símbolo A no topo). A outra transição (de q1 para q0) não exige e não lê nenhum símbolo da entrada, mas exige que o próximo símbolo da pilha seja A. Se for, o autômato muda do estado q1 para o estado q0 e escreve $ na pilha.

Vamos apresentar a seguir como um AP processa (computa) uma cadeia de entrada para indicar se ela faz parte da linguagem ou não.

1.2 Computação e Aceitação no Autômato com Pilha

Vamos começar analisando o comportamento do AP anterior quando ele recebe a cadeia de entrada aa. Em geral, chamaremos a esse processo de teste de uma cadeia de computação. Portanto, o que vamos ver agora é a computação da cadeia aa.

Como dissemos acima, esse autômato tem $ como símbolo inicial da pilha. Observe também que seu estado inicial é q0. Portanto, no início da computação, teríamos a seguinte configuração do autômato:

Na figura acima, o autômato está em seu estado inicial q0, a pilha contém apenas o símbolo $ e a entrada ainda contém toda a cadeia aa. Nessa configuração, temos a como próximo símbolo da entrada e $ como próximo

(6)

Para entender como chegamos aqui, lembre-se que o símbolo a (da cadeia

de entrada) e o símbolo $ (da pilha) foram removidos após serem lidos. Além disso, a cadeia ABC foi inserida na pilha do C para o A. Partindo da configuração representada acima, veja que é possível voltar de q1 para q0 sem ler símbolo da entrada, mas lendo o símbolo A que do topo da pilha. O resultado está representado abaixo:

Veja que a transição de q1 para q0 causou a escrita do símbolo $ na pilha. Assim, temos novamente um símbolo a para ser lido da entrada e um símbolo $ para ser lido da pilha e podemos fazer outra transição para q1:

Neste ponto, a cadeia de entrada já foi completamente lida e o autômato chegou a um estado de aceitação. Como acontecia nos autômatos finitos, essas duas condições são necessárias para concluir que a cadeia aa foi aceita,

(ou seja, faz parte da linguagem que o autômato representa)! O fato da pilha ainda ter símbolos não tem importância nessa decisão. De fato, a cadeia pode

(7)

Veja que, no processo de reconhecimento, existem três informações importantes: o estado atual, o que resta da cadeia de entrada e a pilha atual. Por isso, podemos representar cada configuração de um autômato de pilha simplesmente como triplas na forma (q, s1s2...sn, X1X2...Xp) onde:

• q é o estado atual do autômato

• s1...sn é o restante (ainda não lido) da cadeia de entrada

• X1...Xp é uma cadeia que reflete o conteúdo da pilha, considerando que o símbolo da esquerda X1 representa o “topo” da pilha (como se a pilha tivesse sido “deitada” para a esquerda)

Essas triplas serão chamadas de descrições instantâneas ou IDs (do inglês instantaneous description) . Apesar do nome especial, essas triplas são

apenas uma maneira mais formal e sucinta de representar a “configuração” do autômato em um dado instante.

Vamos considerar que um AP está na seguinte ID genérica: (q, s1s2...sn, X1X2...Xp). Observe que o próximo símbolo da entrada é s1 e o próximo símbolo da pilha é X1. Se houver, neste autômato, uma transição saindo do estado q para o estado r, e na transição tiver o rótulo “s1, X1 / Y1...Yk”, então o autômato pode mudar de estado e de configuração, causando três mudanças na ID:

• trocamos o estado q por r,

• removemos o s1 da entrada e o X1 da pilha,

• acrescentamos Y1...Yk na esquerda (topo) da pilha.

A nova ID seria a tripla (r, s2...sn, Y1...YkX2...Xp). Representamos que esta é uma mudança válida de configuração (ou de ID) assim:

(q, s1...sn, X1...Xp) |- (r, s2...sn, Y1...YkX2...Xp)

(AO DIAGRAMADOR: “|-“ é um símbolo só, como se fosse o símbolo “

(8)

A partir de agora, vamos usar as IDs para representar a computação de uma cadeia em um AP. Vamos dar exemplos usando ainda o mesmo autômato de antes, o qual reproduzimos abaixo:

Como primeiro exemplo, apresentamos abaixo a computação da cadeia aa,

que vimos no início desta seção:

(q0, aa, $) |- (q1, a, ABC) |- (q0, a, $BC) |- (q1, ε, ABCBC)

Compare com as figuras no início da seção e perceba como cada ID está diretamente relacionada a cada figura. Veja que a computação chega a uma ID cujo estado é de aceitação (q1) e cuja entrada está vazia (ε). Como dissemos antes, ssas são as duas condições necessárias para concluirmos que a cadeia

aa foi aceita!

Vamos agora ver o exemplo de uma cadeia que é rejeitada. Segue a computação da cadeia ab:

(q0, ab, $) |- (q1, b, ABC) |- (q0, b, $BC)

Ela começa no estado inicial q0, com a cadeia ab e o símbolo de início $ (primeira ID). A partir do estado q0, o AP lê e remove a da entrada e $ da pilha, indo para q1 e escrevendo ABC (formando a segunda ID). A partir de q1, o AP ignora (não lê) o símbolo da entrada, mas lê e remove o A da pilha, indo para q0 e escrevendo o $ (antes do BC). A computação pára no estado q0 com o símbolo b na entrada e $ na pilha, pois não existe nenhuma seta saindo de q0 com estes dois símbolos. Como a entrada não foi toda lida e o estado q0 não é de aceitação, concluímos que a cadeia é rejeitada.

(9)

cadeia foi aceita. Isso porque usamos a definição de aceitação por estado final. Existe uma definição alternativa, chamada de aceitação por pilha vazia, na qual não importa o estado onde o AP pára, mas é obrigatório que a pilha termine vazia para a cadeia ser aceita.

Neste material, vamos trabalhar apenas com a aceitação por estado final por ser mais parecida com a aceitação dos autômatos finitos do 1º fascículo (AFD, AFND e ε-AFND). O que importa saber é que as duas definições são equivalentes – para todo AP que aceita por estado final existe um AP que aceita por pilha vazia. Caso interesse, você pode pesquisar em outros materiais sobre a aceitação por pilha vazia.

Na próxima seção, damos a definição matemática formal dos autômatos com pilha. É importante que você tenha compreendido bem o que vimos até aqui antes de passar para ela. (Se não compreendeu, releia as seções 1.1 e 1.2 ou entre em contato com seu tutor).

1.3 Definição Formal

Os autômatos com pilha são 7-tuplas (ou seja, estruturas contendo uma seqüência de 7 elementos) na forma:

P = (Q, Σ, ΓΓΓΓ, δ, s, $, F) , onde:

Q é conjunto finito de estados, como nos autômatos finitos

• Σ (sigma) é o conjunto dos símbolos de entrada, como nos autômatos

finitos

• ΓΓΓΓ (gama) é o conjunto dos símbolos da pilha, que são os únicos símbolos que podem ser escritos na pilha

• δ (delta) é a função de transição, parecida com a dos autômatos finitos

(10)

s é o elemento de Q que serve de estado inicial, como também ocorre nos autômatos finitos

$ é um elemento de Γ usado como símbolo inicial da pilha

F é o conjunto de estados de aceitação ou estados finais, como nos autômatos finitos

Se você comparar com a definição dada para os autômatos finitos no 1º fascículo, verá que temos apenas dois novos componentes: Γ e $. Os dois são relacionados à pilha do autômato que estamos vendo. Como os autômatos finitos não tinham pilha, não precisavam desses dois componentes.

Outra diferença para os demais autômatos é a função de transição δ. Ela também está presente nos autômatos finitos, mas é definida de maneira diferente nos APs: δ : Q x (Σ∪∪∪∪{εεεε}) x (ΓΓΓΓ∪∪∪∪{εεεε}) 2Q x ΓΓΓΓ*. Isso quer dizer que ela

recebe como argumento uma tripla assim δ(q,a,X), onde:

q é o estado de onde sai a transição

a é o próximo símbolo da cadeia de entrada ou ε (para não ler nada)

X é o próximo símbolo a ser lido da pilha ou ε (para não ler nada)

Para cada tripla dada como argumento, a função de transição delta dá como resultado um conjunto de pares { (p1, α1), (p2, α2), ..., (pj, αj) }. Cada par indica o próximo estado px e a cadeia que será escrita na pilha αx. Usamos conjunto porque os APs são não-determinísticos e, por isso, podem ter mais de

uma opção de transição para cada entrada. Isso quer dizer que o autômato pode escolher uma das opções:

• Mover para p1 e escrever α1 na pilha,

• OU mover para p2 e escrever α2 na pilha, OU ...,

(11)

!! ATENÇÃO !!

Esse não-determinismo dos APs pode fazer com que haja mais uma computação para uma mesma cadeia. Como nos AFNDs, a cadeia será considerada aceita se existir pelo menos uma computação que leve a um

estado final após ler toda a cadeia. Ou seja, alguma computação deve chegar a uma ID na forma (qx, ε, α), em que qx é algum estado de aceitação e a entrada está vazia (já a pilha pode ter um conteúdo α qualquer).

Sobre a representação da função de transição dos APs, não vamos mais usar tabelas porque é um pouco mais difícil do que antes. Vamos preferir listar todas as opções de transição na forma δ(q,a,X) = { (p1, α1), ..., (pj, αj) } , desde que o conjunto de saída não seja vazio. Se o resultado for um conjunto vazio, simplesmente não escrevemos nada.

Vamos agora fazer a representação formal do AP visto na seção 1.1 e reproduzido abaixo. Vamos chamar o autômato de P1:

É fácil perceber que o conjunto de estados é {q0, q1}, sendo q0 o estado inicial e q1 o único estado de aceitação. É fácil também identificar os símbolos de entrada, pois, na descrição dada naquela seção, dissemos claramente que seria o conjunto {a,b}. Já os símbolos da pilha nós podemos descobrir olhando os rótulos das transições, porém ignorando o primeiro rótulo de cada transição. Assim, os símbolos da pilha são: {$, A, B, C}, sendo $ o símbolo de início da pilha, como informamos na seção 1.1. Assim, já podemos preencher seis componentes da definição formal:

(12)

A função de transição δ1 nós descrevemos com base nas setas da representação gráfica. Veja que temos uma única seta saindo de q0. Ela lê o símbolo a, da entrada, e o símbolo $, da pilha. O efeito dessa transição é fazer o autômato ir para q1 e escrever ABC na pilha. Portanto, temos:

δ1(q0, a, $) = { (q1, ABC) }

A outra seta sai de q1, não lê nada da entrada, mas lê A da pilha. Ela leva para q0 e escreve $ na pilha. Portanto, temos:

δ1(q1, ε, A) = { (qo, $) }

Pronto, essas duas sentenças definem a função δ1. Podemos entender que todas as outras entradas possíveis dão como resultado o conjunto vazio. Por exemplo: δ1(q0, b, A) ou δ1(q1, a, B) dão o resultado ∅.

Este único AP dado como exemplo até agora é ainda muito simples. Ele simplesmente reconhece “todas as cadeias que são formadas apenas por símbolos a”. Esse exemplo ainda não demonstra o poder dos autômatos de

pilha porque essa linguagem nós poderíamos representar com um autômato finito sem dificuldades. A seguir, veremos a construção de um AP para uma linguagem que não pode ser representada com autômatos finitos.

Aprenda praticando

Questão 1: Vimos no capítulo sobre gramáticas livres de contexto (fascículo 2) a linguagem das cadeias na forma 0n1n, para todo n>1. Lá, dissemos que essa linguagem não é regular, mas é livre de contexto. Isso quer

dizer que há alguma gramática livre de contexto e também algum autômato com pilha para representá-la. A gramática já foi apresentada no fascículo 2. Crie agora um AP de nome P2 para representá-la.

Resolução:

(13)

número n de símbolos 1. Assim, o autômato vai precisar “contar” de alguma

maneira a quantidade de símbolos 0, para depois “conferir” se existe a mesma quantidade de 1s.

A idéia é usar a pilha para fazer essa contagem. A cada símbolo 0 lido da cadeia de entrada, colocamos algum símbolo na pilha. Vamos usar X para isso. Depois, a cada símbolo 1 lido da entrada, o autômato P2 deve ler um símbolo X da pilha ao mesmo tempo. O autômato irá para o estado de aceitação se retirarmos todos os Xs da pilha nesse processo, pois isso significa que para cada símbolo X tinha um símbolo 1.

O diagrama do autômato P2 é dado abaixo. Considere que $ é o símbolo de início da pilha.

Veja que a transição de q0 para q0 serve para ler todos os 0s da entrada, colocando os Xs correspondentes na pilha. A transição para q1 só vai acontecer quando houver, ao mesmo tempo, um símbolo 1 na entrada e um símbolo X na pilha. A partir daí, no estado q1, para cada símbolo 1 lido, deve haver um símbolo X na pilha. Se houver a quantidade certa de símbolos 1s, a entrada vai ficar vazia no mesmo momento em que acabarem os símbolos Xs da pilha. A pilha, então, voltará a ter apenas o símbolo inicial $ (que estava “abaixo” dos Xs). Com o símbolo $ na pilha, o autômato pode mover para o estado de aceitação.

(14)

Os estados são facilmente identificáveis na figura. Eles formam o conjunto: {q0,q1,q2}. Desses, temos q0 como estado inicial e o conjunto unitário de estados de aceitação {q2}. Pela descrição dada para linguagem, podemos concluir que os símbolos de entrada são: {0,1}. Por sua vez, os símbolos da pilha você pode descobrir revendo o processo de construção do autômato (ou apenas olhando nas transições do autômato final). Confira que são apenas dois os símbolos da pilha, formando o conjunto: {$,X}. Destes, usamos $ como símbolo de início da pilha.

Falta apenas a função de transição do autômato, que chamaremos de δ2. Ela é construída com base nas transições do autômato, representadas por setas. Por exemplo, temos uma transição de q0 para q0 que lê 0 da entrada e nada (ε) da pilha e, depois escreve X. Essa transição nos leva a concluir que δ2(q0,0,ε) = { (q0, X) }. Fazendo o mesmo para as outras três transições, completamos a definição formal de P2:

P2 = ({q0,q1,q2}, {0,1}, {$,X}, δ2, q0, $, {q2}), onde δ2 é dada por:

δ2(q0,0,ε) = { (q0,X) }

δ2(q0,1,X) = { (q1,ε) }

δ2(q1,1,X) = { (q1,ε) }

δ2(q1,ε,$) = { (q2,$) }

Questão 3: Mostre a computação do AP da questão anterior quando ele recebe a cadeia 0011. Diga se esta cadeia é aceita e justifique.

Resolução:

Começamos no estado inicial q0, com a entrada 0011 e com a pilha com seu símbolo de início $:

(15)

Podemos agora fazer a transição de q0 para q0 que lê 0 e escreve X na pilha, o que nos dá a ID:

(q0, 011, X$)

Podemos fazer novamente a mesma transição:

(q0, 11, XX$)

Veja que já lemos os dois 0s e, como resultado, escrevemos dois Xs na pilha. O que o autômato vai fazer a partir de agora é como se ele “conferisse” que há um símbolo 1 para cada X. Veja que, neste ponto, só podemos fazer a transição de q0 para q1 que lê justamente um 1 e um X juntos, dando o resultado:

(q1, 1, X$)

Agora podemos fazer uma transição de q1 para q1 que faz algo parecido:

(q1, ε, $)

Observe que cadeia já está vazia, mas ainda não estamos em um estado de aceitação. Por sorte, ainda podemos fazer uma transição que não lê símbolo da entrada, e lê $ da pilha. Ela leva de q1 para q2, resultando na ID:

(q2, ε, $)

Veja que chegamos a uma configuração com um estado de aceitação e com a entrada vazia. Portanto, podemos concluir que a cadeia 0011 é aceita.

Nós detalhamos com bastante cuidado todo o processo de reconhecimento para facilitar o seu entendimento, mas, nas suas respostas em exercícios ou provas, você pode ser mais objetivo e listar diretamente toda a computação assim:

(q0, 0011, $) |- (q0, 011, X$) |- (q0, 11, XX$)

(16)

Saiba mais

A apresentação inicial dos autômatos com pilha na seção 1.1 foi baseado no livro de Sipser, que recomendamos pela sua boa didática. Porém, os principais detalhes do presente capítulo, tais como definição formal, computação e aceitação em APs, estão mais parecidos com o livro de Hopcroft, Ullman e Motwani. Por isso, este livro é a principal leitura complementar recomendada para o assunto.

Um assunto interessante presente em ambos os livros citados é prova da equivalência entre gramáticas livres de contexto e autômatos de pilha. Nós apenas citamos aqui que esses dois modelos são equivalentes, mas o livro vai além e descreve detalhadamente como converter de um modelo para o outro.

Atividades e Orientações para estudo

Abaixo apresentamos algumas atividades que servirão para você, cursista, fixar o assunto aqui apresentado. Tente resolver os exercícios aqui apresentados e, em caso de dúvida, consulte o tutor ou o professor.

Questão 1: Considerando o autômato P2 dado antes, mostre a computação de cada uma das cadeias abaixo e diga se cada cadeia é ou não aceita:

a) 01

b) 001

c) 000111

(17)

Questão 2: Crie um autômato P3 para representar a linguagem das cadeias na forma 0n12n, para n>1. Ou seja, são cadeias que iniciam com um número qualquer (n) de símbolos 0s e que, depois, têm um número duas vezes maior

(2n) de símbolos 1s. (DICA: use uma idéia muito parecida com a que usamos

para criar P2, porém o novo autômato, para cada 0 lido, você deve preparar o autômato para ler dois 1s).

Questão 3: Vimos que os APs são não-determinísticos, mas só demos exemplos de APs determinísticos. Abaixo, mostramos um exemplo de APs não-determinístico para reconhecer cadeias na forma w.wr, ou seja, cadeias cuja segunda metade é o inverso da primeira.

Por ser (verdadeiramente) não-determinístico, o autômato P4 pode permitir mais de uma computação para uma cadeia dada. Para cada cadeia abaixo, encontre alguma computação que comprove que ela é aceita pelo autômato. (Já estamos afirmando que todas são aceitas. Falta achar uma computação que comprove isso).

a) aa

b) abba

c) bbbb

(18)
(19)

Capítulo 2 –

Máquinas de Turing

Talvez você, cursista, tenha chegado neste ponto do curso ainda sem saber exatamente o que os modelos matemáticos vistos têm a ver com os computadores modernos. Se este for o seu caso, não se preocupe, pois o que veremos neste capítulo o fará entender melhor a relação entre os modelos matemáticas e os computadores que usamos.

Primeiramente, veremos mais um modelo matemático para representação de linguagens – as Máquinas de Turing (MTs). Apesar de sua aparente simplicidade, este modelo é mais poderoso do que todos os modelos que vimos antes. Aliás, nenhum outro modelo matemático é capaz de representar mais linguagens do que ele.

Devido a essa grande capacidade das máquinas de Turing, elas é que são usadas como base para o estudo teórico dos limites dos computadores reais criados pelo homem. Acredita-se, por exemplo, que nunca haverá um computador capaz de resolver mais problemas do que as máquinas de Turing.

Antes de nos aprofundarmos nessa discussão, vamos aprender como funcionam as Máquinas de Turing (que abreviaremos como MTs).

2.1 Princípio de Funcionamento das MTs

(20)

armazenar dados em computadores antigos1. Na máquina de Turing, cada posição da fita guarda algum símbolo. Esses símbolos são lidos em seqüência, um por vez, como faz a “cabeça” ou “cabeçote” nas fitas magnéticas reais.

A cadeia de entrada da máquina de Turing é automaticamente gravada na fita quando a máquina é iniciada. Como a fita é infinita, as (infinitas) posições mais à esquerda e mais à direita da cadeia são preenchidas com um símbolo

especial que chamaremos de símbolo branco. Por exemplo, se

considerarmos que a cadeia de entrada é abab e que o símbolo branco é representado por , a fita da MT seria iniciada assim:

A MT começa com a “cabeça” posicionada sobre o primeiro símbolo da cadeia de entrada e, a partir daí, começa a operar. A cada etapa de sua operação, a MT faz três ações na fita: ela lê o símbolo que está sob a cabeça, escreve outro símbolo sobre ele (substituindo-o) e move a cabeça uma única posição, para a esquerda ou para a direita. Essas três ações ocorrem em conjunto, levando a máquina a caminhar na fita uma posição por vez em qualquer direção.

Para representar uma MT, podemos usar um diagrama de estados parecido com o dos autômatos finitos e dos autômatos com Pilha. Novamente, temos um estado inicial e zero ou mais estados de aceitação, representados da mesma maneira que antes. Porém, as setas das transições recebem rótulos diferentes dos usados nos outros autômatos. Cada transição tem um rótulo:

X / Y, M , onde:

X é o símbolo que precisa ser lido da fita (pela cabeça)

1

Também é usada em computadores modernos, em algumas aplicações restritas (por exemplo: para

(21)

Y é símbolo que será escrito na fita (substituindo X)

M indica a direção para onde a cabeça se moverá na fita, podendo assumir apenas dois valores:

o E, para “esquerda” (também pode ser usado L, do inglês left)

o D, para “direita” (também pode ser usado R, do inglês right)

Para ilustrar, mostramos abaixo um primeiro exemplo de MT, que aceita cadeias sobre o alfabeto {a,b}:

Para explicar este primeiro exemplo de MT, vamos detalhar como ela manipula a fita. A idéia usada na construção da máquina é que, toda vez que ele encontrar um b na fita, ela vai escrever X no lugar e vai voltar uma posição. Isso acontece na transição “b/X,E” em q0. Já se a MT dada ler um a, ela vai andar duas posições para a direita. A primeira posição ela anda ao encontrar o próprio a, como você pode conferir na transição “a/a,D” de q0 para q2. A segunda posição ela anda qualquer que seja o símbolo, como você pode ver nas várias opções de transição de q2 para q0.

Se em algum momento, no estado q0, a máquina encontrar o símbolo vazio, ela vai para o estado de aceitação q1 e ali irá parar. Entenda que uma máquina de Turing pára em um estado quando nenhuma transição pode ser usada a

(22)

Destacamos ainda que, nas máquinas de Turing, a cadeia não precisa ser lida inteira para ser aceita, como acontece nos outros tipos de autômatos. A única coisa que importa é que a MT pare em um estado de aceitação. Por isso, toda vez que a MT mostrada acima chegar ao estado q1, ela não só irá parar como também irá aceitar a cadeia (mesmo que ela não tenha sido lido inteira).

Como fizemos com os APs, vamos dedicar uma seção inteira aos detalhes do processo de reconhecimento em uma MT.

2.2 Computação e Aceitação nas Máquinas de Turing

Vamos começar analisando o comportamento da MT dada quando ela recebe a cadeia aab como entrada. A configuração inicial da MT é exibida graficamente abaixo:

(23)

Agora, temos a cabeça de leitura apontando para outra ocorrência do símbolo a. Este é um ponto interessante para lembrar a você, cursista, que o movimento da cabeça da fita e a mudança entre os estados são coisas distintas. A mudança de estados é definida pelas setas, enquanto a direção da fita é definida pelo terceiro elemento do rótulo da seta (que pode ser E ou D). Veja que, neste ponto, a MT vai fazer uma transição de volta ao estado q0, mas movendo a cabeça para a direita. O resultado é mostrado abaixo:

(24)

Estamos novamente no estado q0 com a cabeça apontando para um símbolo a. Você agora já deve ser capaz de perceber que a MT vai mudar para q2 e a fita vai andar para a direita, resultando na configuração:

Em q2 e com o símbolo X sendo lido pela cabeça, a máquina vai voltar para q0 com a fita andando para a direita. O resultado é a seguinte configuração:

(25)

configuração será o estado q1 com a cabeça da fita posicionada um símbolo à esquerda, assim:

Agora a máquina chegou a um estado do qual não sai nenhuma transição. Portanto, dizemos que a MT parou no estado q1. Como q1 é um estado de aceitação, concluímos que a cadeia aab é aceita pela máquina dada. Em

outras palavras, a cadeia aab faz parte da linguagem que a MT representa.

Se você entendeu o processo de reconhecimento descrito acima, não terá dificuldades para entender o que vamos definir a seguir. (Se ainda estiver inseguro, aconselhamos você a reler cuidadosamente a partir do início da seção.)

Como fizemos com os APs, vamos mostrar uma representação mais sucinta de cada configuração do autômato. Mas antes, pense um pouco: quais elementos são importantes na configuração de uma MT?

Um elemento é fácil de perceber: o estado do autômato. Não precisamos mostrar todo o diagrama a cada passo, como fizemos acima. Basta informar o estado onde a MT está a cada instante.

(26)

Os três elementos citados vão formar a descrição instantânea ou ID (instantaneous description) de uma máquina de Turing. Para simplificar, uma

ID será representada na seguinte forma:

<fita à esquerda>, <estado>, <posição atual + fita à direita>

Um detalhe é que a fita de uma MT possui infinitos símbolos brancos, tanto à esquerda quando à direita, que poderiam dificultar a representação. Usaremos duas regras para lidar com isso:

• Em primeiro lugar, não representaremos seqüência infinitas de símbolos brancos que ocorrerem na extrema esquerda de <fita à esquerda> ou na extrema direita de <posição atual + fita à direita>.

• Em segundo lugar, se uma das duas partes da fita ficar vazia, colocaremos um símbolo (do trecho infinito que foi omitido).

Vejamos agora como representar com IDs a computação da cadeia aab (a mesma que fizemos antes de maneira gráfica). A configuração inicial da MT inclui o estado q0. O lado esquerdo da fita é composto apenas de símbolos brancos, que representaremos com um só (para não ficar vazia). Já a outra parte da fita, é formada justamente pela cadeia aab. Assim a ID inicial será:

, q0, aab

Como fizemos com os APs, representaremos mudanças de IDs válidas nas máquinas de Turing com o símbolo |-. Assim, o processamento da cadeia aab pode ser representado pela seqüência de IDs mostrada abaixo. Compare com as configurações apresentadas anteriormente com figuras.

, q0 , aab

|- a, q2, ab

|- aa, q0, b

(27)

|- aa, q2, X

|- aaX, q0,

|- aa, q1, X

Atente para o detalhe de que o primeiro símbolo depois do estado representa a posição que será lida pela cabeça e que servirá para decidir a próxima configuração. Na primeira ID foi lido um “a”, o que levou ao estado q2 e causou um movimento para a direita, como pode ser visto na segunda ID. Na segunda ID, foi lido o segundo a, que causou a mudança para q0, etc.

Observe, ainda, que na primeira e na sexta IDs tivemos que mostrar um símbolo branco da seqüência infinita de alguma das extremidades lado da fita. . Lembre-se que, no fundo, a primeira ID, por exemplo, representa algo assim:

(infinitos)... , q0, aab ... (infinitos)

Nas outras IDs, a MT estava em posições intermediárias da cadeia e, por isso, omitimos todos os símbolos brancos.

Consideramos que uma cadeia w dada como entrada para uma MT será aceita se a computação dela tiver as seguintes características:

• Inicia em uma ID na forma , q0, w, onde q0 é o estado inicial

• Termina em uma ID qualquer αααα, qx, ββββ , de maneira que a MT não possa mais sair dessa configuração.

• O estado qx desta última ID é um estado de aceitação.

De maneira parecida, a cadeia será considerada rejeitada se a computação dela satisfizer as duas primeiras condições (de sair da configuração inicial e parar), mas não satisfizer a terceira (de terminar em um estado de aceitação).

(28)

Existem situações em que a MT não consegue satisfazer a segunda condição dada antes: de “parar” em alguma configuração.

Para exemplificar, vamos usar a seguinte máquina de Turing T2, que recebe entradas sobre o alfabeto {a,b}:

Se você tentar entender essa MT verá que ela aceita apenas as cadeias formadas apenas por símbolos a’s. Mas o que acontece se a cadeia tiver um b? Vamos analisar o comportamento de T2 quando ela recebe a entrada ab para entendermos. A computação resultante é descrita abaixo:

, q0, ab

|- A, q0, b

|- AB, q1,

|- ABC, q1,

|- ABCC, q1,

|- ABCCC, q1,

|- ...

Perceba que, depois de entrar em q1, a MT começa a trocar cada (branco) por C, seguindo para a direita. Porém, seguindo à direita ela sempre encontra outro (pois a fita tem infinitos deles) e o processo se repete indefinidamente. Ou seja, essa MT nunca vai parar!

(29)

chega ser devidamente rejeitada. De maneira informal, podemos dizer que a cadeia “deveria ser rejeitada, mas a MT não consegue parar para rejeitar”.

Esse comportamento não é desejável em uma MT. A realidade é que, em muitos casos, é possível criar uma MT que nunca entra em loop, qualquer que seja a entrada. Porém, em outros casos isso não é possível. Não entraremos em detalhes porque esse assunto será visto no próximo capítulo.

O importante é que já vimos todos os detalhes de funcionamento das MTs e agora podemos apresentar a definição matemática precisa desse modelo.

2.3 Definição Formal

As máquinas de Turing podem ser definidas matematicamente como 7-tuplas contendo os componentes descritos abaixo:

T = (Q, Σ, ΓΓΓΓ, δ, s, , F) , onde:

Q é conjunto finito de estados

• Σ (sigma) é o conjunto dos símbolos de entrada

• ΓΓΓΓ (gama) é o conjunto dos símbolos de fita, que são os símbolos que podem ser lidos e escritos na pilha, incluindo todo o conjunto Σ

• δ (delta) é a função de transição, que deixaremos para descrever

melhor abaixo

s é o elemento de Q que serve de estado inicial

• é o símbolo branco, que é um elemento de ΓΓΓΓ mas não de Σ, ou seja,

ele aparece na fita mas não pode aparecer em cadeias de entrada

F é o conjunto de estados de aceitação ou estados finais

(30)

As definições de todos os modelos de autômatos variam em dois ou três dos componentes, mas o componente que é o principal responsável pela forma de operação específica de cada um é a função de transição δ. Por esse motivo, falaremos somente sobre ela a partir de agora.

Aqui, ela é definida como δ : Q x ΓΓΓΓ → Q x {E,D} . Isso quer dizer que ela

recebe como argumento um par assim δ(q,X), onde:

q é o estado de onde sai a transição

X é o símbolo na próxima posição da fita

O valor da função, se estiver definido, é uma tripla (p,Y,M) onde:

p é o próximo estado

Y é o símbolo que será escrito sobre o X (substituindo-o)

M é a direção de movimento da cabeça, podendo assumir apenas os valores E (esquerda) ou D (direita)

Como nos outros autômatos, o que a função de transição representa é o mesmo que as setas entre os estados da representação gráfica representam. Aquilo que formalmente dizemos assim δ(q0,X) = (q1,Y,D) , graficamente é representado assim:

O estado de onde sai a seta (q0) e o símbolo antes da barra (X) são os dois argumentos da função, enquanto que o estado onde chega a seta (q1), o símbolo depois da barra (Y) e a direção da fita (D, de direita), formam o resultado da função.

(31)

Os estados de T1 são facilmente identificáveis: {q0, q1, q2}, onde q0 é estado inicial e o conjunto de estados de aceitação é o conjunto unitário {q1}. Os símbolos de entrada formam o conjunto {a,b}, como dissemos quando apresentamos esta MT na primeira seção. Já os símbolos da fita incluem todos os símbolos usados: {a, b, X, }2, onde é o símbolo branco. Com isso, já podemos dar quase todos os detalhes da representação formal:

T1 = ({q0, q1, q2}, {a,b}, {a,b,X, }, δ1, q0, , {q1})

O que falta representar é a função de transição δ1. Veja que as funções de transição das MTs recebem apenas duas entradas. Isso nos permite representá-las com tabelas. Como nos autômatos finitos, usaremos as linhas para os estados e as colunas para os símbolos de fita. No encontro de linha e coluna colocaremos a tripla que representa o valor da função. Assim, a função δ1 pode ser representada pela seguinte tabela:

a b X

q0 (q2, a, D) (q0, X, E) - (q1, , E)

q1 - - - -

q2 (q0, a, D) (q0, b, D) (q0, X, D) (q0, , D)

2

(32)

Podemos perceber na tabela acima que, dado um estado e um símbolo, a máquina oferece uma das duas opções: ou existe uma opção de movimento única (dada pela tripla) ou não existe opção de movimento (representada com um traço). Por isso, em um dado instante em toda máquina de Turing, sabemos sempre exatamente o que fazer: se houver a tripla, a MT faz o movimento; se não houver, a MT pára. Nelas não existem múltiplas opções de movimento para um mesmo par (estado, símbolo)

Isso significa que as MTs que nós definimos são determinísticas.. Você deve lembrar que os autômatos que apresentavam ambigüidades de movimento, nós chamamos antes de não-determinísticos. O exemplo mais

recente que vimos foram os autômatos com pilha. Definimos os APs daquela maneira porque, se os definíssemos como determinísticos, eles seriam menos

poderosos. Porém, as Máquinas de Turing determinísticas e não-determinísticas têm o mesmo poder! É possível transformar uma MT de um tipo em uma MT do outro tipo. Por isso, preferimos trabalhar com o tipo mais simples que é a MT determinística.

Seguem alguns exercícios sobre MTs para ajudar a fixar o assunto.

Aprenda praticando

Questão 1: Represente formalmente o autômato T2 (que é o mesmo que usamos para dar exemplo de loop infinito na seção 2.2).

(33)

Os estados formam o conjunto {q0, q1}, onde q0 é estado inicial e o único estado de aceitação. Os símbolos de entrada são {a,b}, como pode ser lido na descrição original na seção 2.2. Já o alfabeto da pilha tem a mais os símbolos A, B, C e , onde é o símbolo branco.

Com isso, podemos terminar a representação formal de T2, que fica assim:

T1 = ({q0, q1}, {a,b}, {a,b,A, B,C, }, δ2, q0, , {q0}), onde δ2 é:

a b A B C

q0 (q0,A,D) (q1,B,D) - - - -

q1 - - - (q1,C,D)

Em um caso como este, que a MT não está definida para muitas configurações, teria sido mais simples representar os valores da função assim:

δ2(q0,a) = (q0,A,D)

δ2(q0,b) = (q1,B,D)

δ2(q1, ) = (q1,C,D)

As duas maneiras são equivalentes, então fique à vontade para escolher como fazer, nos exercícios.

(34)

>> Ao diagramador: Nas setas, trocar ponto-e-vírgula por barra “/”. Trocar também a letra L (left) por E (esquerda) e trocar R (right) por D (direita) <<

a) 01

b) 001

Resolução da letra a:

Iniciamos a computação com uma ID contendo o estado inicial com a cadeia à sua direita:

, q0, 01

A partir dai, fazemos os movimentos válidos na MT até ela parar (quando não tiver mais movimento válido). Na ID acima, a máquina está em q0 lendo o símbolo 0, portanto ela vai mover para q1, vai trocar o 0 por A e, depois, vai andar na fita para a direita. A configuração resultante será essa:

A, q1, 1

(35)

, q2, AB

Em q2, lendo A, a máquina muda para q0, troca A por A (ou seja, não muda) e anda para a direita na fita:

A, q0, B

Em q0, lendo B a máquina irá para q4 e anda para a direita na fita, produzindo a seguinte configuração:

AB, q4,

Em q4, ao ler o símbolo branco , a MT vai para o estado q5, gerando a seguinte ID:

AB , q5,

Neste estado, a MT não tem mais opção de movimento – ela parou. Como a computação terminou no estado de aceitação q5, concluímos que a cadeia 01 (dada no início) foi aceita!

Resolução da letra b:

Dessa vez, daremos a resposta de maneira mais direta e deixaremos por sua conta interpretar o que aconteceu a cada passo. A computação dessa cadeia é a seguinte seqüência de IDs:

, q0, 001

|- A, q1, 01

|- A0, q1,1

|- A, q2, 0B

(36)

|- AA, q1, B

|- AAB, q1,

A máquina pára no estado q1, que não é estado de aceitação. Por isso, a cadeia 001 não é aceita por essa máquina de Turing!

2.4 Noções de Teoria da Computabilidade

O que vamos apresentar agora é uma visão introdutória da subárea da Teoria da Computação conhecida pelo nome de Teoria da Computabilidade.

Um conceito importante para essa área é o conceito informal de “algoritmo”, que podemos definir assim:

Um algoritmo é uma descrição precisa dos passos que uma máquina (um

humano) deve seguir para resolver, em tempo finito, um problema

matemático.

Podemos dizer que um algoritmo é a “lógica interna” de uma máquina para resolver um problema. Podemos chamar essas máquinas de “computadores”, porque elas computam (ou seja, calculam) a solução do problema. (Por enquanto, vamos pensar que cada computador trata um problema único.)

Com isso, podemos descrever a área assim:

A Teoria da Computabilidade estuda quais problemas matemáticos podem

e quais não podem ser resolvidos por meio de alguma máquina

(computador) em tempo finito.

(37)

Alguns exemplos de problemas matemáticos que podem ser tratados assim são descritos abaixo:

• Somar dois números inteiros

o entradas: dois números a e b

o saída: um número que seja soma de a e b

• Verificar se um número é par

o entrada: um número

o saída: sim/não

• Encontrar o menor caminho de um ponto a outro de uma cidade

o entradas: mapa da cidade e das duas localizações x e y

o saída: caminho de x para y

• Encontrar raízes inteiras de um polinômio

o entrada: um polinômio

o saída: lista de raízes inteiras

A verdade é que já temos criados soluções para problemas assim ao longo de toda a disciplina. Porém, os problemas foram dados na forma de uma

Computador para resolver um problema P

(38)

equivale ao problema de “verificar se uma quantidade de 0’s é par”. Além disso, nos nossos estudos até agora, as “entradas” foram sempre dadas na forma de cadeias e as saídas foram sempre ou sim ou não (que chamávamos

de aceita ou rejeita).

Dos exemplos anteriores, apenas o segundo (verificar se um número é par) tem saídas nessa forma. Mas isso não atrapalha nossos estudos, pois, na verdade, quase todos os problemas matemáticos podem ser modificados para usarem apenas saídas sim/não. Podemos transformar os outros três problemas dados antes em problemas de verificar se existe uma resposta ou em

problemas de verificar se uma resposta (dada pela entrada) está correta. Os

problemas ficariam assim:

• Verificar soma de números inteiros

o entrada: três números a, b e c, onde c deveria valer a soma de a

e b

o saída: sim (se c for a soma de a e b) / não (caso contrário)

• Verificar o menor caminho de um ponto a outro de uma cidade

o entrada: mapa da cidade e um caminho de x para y

o saída: sim (se o caminho dado for o menor que existe para ir de x para y) / não (caso contrário)

• Verificar se um polinômio tem raízes inteiras

o entrada: um polinômio

o saída: sim (se o polinômio tem raízes inteiras) / não (caso contrário)

(39)

decisão. Ou seja, estávamos tentando provar que era possível criar um computador que resolve um problema de decisão:

Chamaremos um problema (ou uma linguagem) de decidível se for possível construir uma máquina para resolvê-lo (computá-lo) em tempo finito. Caso contrário, o problema será chamado de indecidível, o que representa que nenhum computador pode resolver o problema adequadamente, pois entraria em loop infinito para algumas entradas.

ATENÇÃO

Não confunda os termos! Os problemas todos que iremos tratar recebem o nome de “problema de decisão”, mas o nosso desafio será classificá-los como problemas decidíveis ou indecidíveis. Assim, o conceito de “problema decidível” é um caso especial do conceito de “problema de decisão”.

O que você talvez ainda esteja questionando é que não detalhamos a construção de nenhum “computador” real na disciplina. Realmente não vimos detalhes físicos da construção, porém, vimos o que realmente importa no computador, que é a sua “lógica interna”, o seu “algoritmo”. E esses algoritmos foram representados com os vários modelos vistos, mas, principalmente com os autômatos: AFD, AFND, ε-AFND, AP e, agora, MT.

Computador para representar uma linguagem L(ou seja, para

resolver um problema de decisão P)

(40)

Por isso, ao representar a solução de um problema (ou uma linguagem) com um desses modelos, estamos provando que o problema (ou a linguagem)

é decidível. Nesse caso, dizemos também que o autômato “decide” o dado

problema (ou a dada linguagem). Com isso, podemos afirmar que os problemas e linguagens que estudamos nos capítulos anteriores são todos decidíveis.

Porém, como você deve lembrar alguns dos modelos vistos decidem mais linguagens e outros decidem menos, formando classes de linguagens (e de problemas). Essa classificação forma a chamada Hierarquia de Chomsky, que discutiremos na próxima seção.

2.5 Hierarquia de Chomsky

Como já vimos no 2º fascículo, a Hierarquia de Chomsky agrupa as linguagens de acordo com os modelos que são capazes de decidi-las. Agora que vimos o último modelo computacional (MT), podemos apresentar essa hierarquia de maneira completa. Antes disso, vamos fazer uma rápida revisão de todos os tipos de autômatos vistos, bem como das classes de linguagens que eles representam.

É curioso observar que o poder para decidir linguagens de cada autômato parece depender do tipo de “memória” que ele possui e de como essa memória pode ser acessada. Por exemplo, os três modelos de autômatos finitos (AFD, AFND e ε-AFND) não têm nenhuma memória auxiliar. Por isso, eles são os modelos menos poderosos que estudamos. Chamamos as linguagens que eles são capazes de decidir de linguagens regulares.

Computadores baseados em autômatos finitos

(41)

Já os autômatos com pilha (APs) têm uma memória infinita (a pilha) que funciona segundo a regra “o último que entra é o primeiro que sai”. Por isso, estes autômatos são capazes de decidir um conjunto maior de linguagens. Chamamos a essas linguagens de linguagens livres de contexto.

Computadores baseados em autômatos com pilha

Por fim, vimos as máquinas de Turing como autômatos com uma memória unidimensional infinita (a fita) que dá total liberdade para ler e escrever em qualquer posição. Como conseqüência, este é o modelo que é capaz de decidir mais linguagens do que todos os outros modelos vistos!

Computadores baseados em máquinas de Turing

O que ainda não fizemos até aqui foi dar nome à classe de linguagens que esse modelo representa. Antes disso, precisamos lembrar que só podemos considerar as MTs que sempre param (ou seja, nunca entram em loop), afinal, a definição de “decidível” exige que a máquina execute em tempo finito (e isso

w sim/não

(42)

podem ser computadas por MTs que sempre param são chamadas de linguagens recursivas. Essa é a classe de linguagens mais abrangente, englobando as outras duas.

As três classes de linguagens apresentadas estão organizadas na chamada Hierarquia de Chomsky3, representada abaixo. Veja que cada nível engloba os níveis inferiores. Assim, toda linguagem regular é também livre de contexto e também recursiva. Isso equivale a dizer que tudo que podemos decidir com um AFD também podemos decidir com um AP e também com uma MT.

Isso ressalta a afirmação que já fizemos antes sobre as MTs – que esse é o modelo mais poderoso que vimos até agora. O nosso próximo passo, agora, é tratar uma questão importante ainda não discutida: será que existe outro modelo capaz de decidir mais linguagens (e problemas) do que as MTs? Trataremos disso na seção seguinte.

2.5 Tese de Church-Turing

No início do século passado, ainda antes dos computadores existirem na forma que conhecemos, houve um grande debate científico sobre como representar da melhor maneira possível os “algoritmos”. Na época, ainda não havia modelos matemáticos para representá-los e os pesquisadores estavam

3

Na verdade, a hierarquia de Chomsky original continha outras duas classes e não continha a classe das

(43)

buscando criar o modelo capaz de representar algoritmos da maneira mais abrangente possível.

Na década de 1930, dois pesquisadores apresentaram, de maneira independente, modelos que se tornaram bastante conhecidos. Alonzo Church apresentou o modelo chamado λ-cálculo (que não veremos) e Alan Turing

apresentou o modelo máquina de Turing (que estamos estudando). Ambos os modelos se mostraram capazes de representar uma quantidade muito grande de algoritmos para diferentes problemas. Mais do que isso, Alan Turing também provou que os dois modelos eram equivalentes, ou seja, podiam resolver os mesmos problemas.

Com o passar do tempo, muitos novos modelos foram propostos, mas nenhum deles se mostrou capaz de resolver mais problemas do que os dois modelos citados. No máximo, os novos modelos se mostraram equivalentes aos dois. Por isso, hoje em dia aceita-se a idéia de que esses dois modelos (λ -cálculo e máquina de Turing) são os modelos que conseguem resolver mais problemas dentre todos os que existem e, provavelmente, dentre todos que podem vir a existir.

Isso é uma conseqüência da chamada Tese de Church-Turing, que definimos aqui da seguinte maneira:

O modelo Máquina de Turing (ou o λ-cálculo) é capaz de representar tudo

aquilo que se chama “algoritmo”.

Ou seja, tudo que se pode calcular por meio de uma máquina real construída pelo homem, também pode ser calculado por meio de uma máquina de Turing. Isso quer dizer que não importa como um computador seja construído de fato. Não importa quanta memória ele tenha nem a maneira de acessá-la. O máximo que podemos conseguir é resolver os mesmos problemas que as máquinas de Turing.

(44)

novo computador que surge não muda em nada essa realidade, pois, os computadores modernos evoluem apenas na velocidade, mas não no poder de resolver problemas.

Assim, o modelo matemático Máquina de Turing, apesar da sua simplicidade, é ainda muito importante no estudo da Computação moderna. Aquilo que você provar que ele não pode resolver, estará provando também que não pode ser resolvido por nenhum computador real, nem no presente nem no futuro.

Atividades e Orientações para estudo

Abaixo apresentamos algumas atividades que servirão para você, cursista, fixar o assunto apresentado. Recomendamos a você que tente resolver e, em caso de dúvidas, que interaja com os tutores e com colegas no ambiente.

(45)

>> À diagramação: Nas setas, trocar: ponto-e-vírgula por barra “/”. Trocar também a letra L (left) por E (esquerda) e trocar R (right) por D (direita) <<

a) ab

b) abc

c) abbc

d) aabc

e) aabbcc

Questão 2: Dê a representação formal da máquina T4, usada na questão anterior.

(46)

a) aa

b) abba

c) aab

d) bb

Questão 4: Crie uma máquina de Turing com alfabeto de entrada {0,1} que entre em loop infinito para alguma cadeia de entrada. (DICA: você pode fazer uma que fique apagando e reescrevendo algo na fita ou você pode fazer uma para avançar a fita na direção dos símbolos brancos indefinidamente).

Questão 5: Responda às seguintes questões:

a) O que é um problema de decisão?

(47)

c) Qual a relação entre os dois conceitos?

Questão 6: Diga os nomes de todas as classes de linguagens estudadas no curso. Para cada classe de linguagens, diga o nome de um modelo de autômato capaz de decidir exatamente essa classe.

Questão 7: Explique, com base na Tese de Church-Turing, qual a relação entre a classe das linguagens recursivas com o conjunto formado por todas as linguagens decidíveis. Explique se são classes iguais ou se uma delas inclui a

outra.

Saiba mais

(48)

Capítulo 3 –

Máquina de Turing Universal e o Problema da Parada

No capítulo anterior, vimos as Máquinas de Turing, que são os modelos matemáticos de computadores que têm a maior capacidade de reconhecer linguagens (e de resolver problemas). Capacidade essa que é considerada o limite teórico para todas as máquinas de computar construídas pelo homem, segundo a tese de Church-Turing.

O que veremos neste capítulo são os limites do modelo Máquina de Turing. Veremos os dois lados da moeda: a sua admirável capacidade de simular a si próprio e a sua incapacidade de decidir algumas linguagens (e, conseqüentemente, de resolver alguns problemas).

Vamos começar discutindo a Máquina de Turing Universal, que é uma MT capaz de simular qualquer outra MT. Depois, usaremos a própria Máquina de Turing Universal para mostrar o Problema da Parada, que é um problema (ou uma linguagem) que não pode ser decidida por nenhuma MT.

3.1 Máquina de Turing Universal (MTU)

Até o momento, vimos MTs de propósitos específicos. Ou seja, cada MT que demos como exemplo representava uma única linguagem simples, como: a linguagem das palavras formadas apenas por a’s ou a linguagem das palavras anbncn, com n1. Essas MTs seriam como computadores muito restritos que resolvem um só problema.

(49)

não seria um indicativo de que os computadores que usamos são mais poderosos do que as MTs?

Não! Como já dissemos no capítulo anterior, os computadores modernos são, no máximo, equivalentes às MTs (se esquecermos que eles têm memória

finita). E nós vamos mostrar, nesta primeira seção, que também existe uma MT geral que pode ser “programada” para resolver diversos problemas. Em especial, essa MT pode simular qualquer outra MT imaginável. Por isso, ela recebe o nome de “Máquina de Turing Universal” ou MTU.

De certa forma, a MTU sozinha pode resolver todos os problemas que qualquer outra MT pode resolver. Mas para isso, a MTU precisa receber não só a cadeia w que será testada (ou a entrada de um problema), como também a

descrição da MT X que se deseja simular. A MTU, então, vai simular o que X

faria ao receber w, retornando, no final, o resultado (sim/não) que X retornaria. A figura abaixo ilustra essa idéia:

Essa descrição de X teria, na MTU, uma importância parecida com a que um “programa” tem nos computadores que usamos hoje em dia. Isso porque o que ambos fazem (tanto a descrição de X como o programa) é descrever como a máquina deve se comportar. Da mesma forma como usamos diferentes programas para fazer tarefas diferentes nos computadores modernos, também podemos dizer à MTU como resolver diferentes problemas passando para ela as descrições das diversas MTs que decidem cada problema.

Um detalhe na figura anterior que ainda não está muito correto é que ela mostra duas entradas para a MTU. No entanto, sabemos que toda Máquina de

Máquina de Turing Universal (vai simular a ação de X

quando X recebe w)

w

sim/não

(50)

fazer dar uma descrição da máquina X na forma de uma cadeia, que representaremos abstratamente como <X>. Ainda assim, teríamos duas cadeias: <X> e w. Vamos unir essas duas cadeias em uma só cadeia, que vamos representar abstratamente como <X,w>.

Assim, quando escrevermos algo como <X,w>, entenda isso como uma cadeia em que podemos separar a parte <X> da parte w, onde a parte <X> é a descrição de uma máquina de Turing e w é uma cadeia de entrada para X.

ATENÇÃO

Fazer essa codificação de uma máquina de Turing X e de w em uma cadeia única <X, w> pode parecer difícil, mas você pode ter certeza de que é uma tarefa possível!

Aliás, é possível transformar em cadeias não só uma MT como também diversas outras informações complexas tais como: figuras, textos, músicas e vídeos. De fato, todas essas informações são codificadas nos nossos computares como cadeias (imensas) do alfabeto binário {0,1}.

Para o leitor interessado, nós explicamos detalhadamente no Apêndice A como fazer a codificação <X, w> usando esse mesmo alfabeto.

A figura abaixo ilustra a MTU de maneira mais correta, recebendo uma só cadeia:

MTU

(vai simular a ação de X quando X recebe w)

(51)

Não vamos definir a MTU em todos os seus detalhes, pois essa máquina teria, pelo menos, algumas dezenas de estados. O nosso objetivo é apenas mostrar que é possível usar o modelo Máquina de Turing para criar uma

máquina universal que simula qualquer MT. Por isso, no restante da seção, daremos apenas a idéia geral de como essa máquina de Turing Universal funcionaria. Com base nesses detalhes e com algum esforço, um aluno interessado é capaz definir de maneira completa uma MTU.

Para o restante da explicação, vamos representar de maneira abstrata como a informação <X, w> é disposta na fita da MTU usando figuras. A figura abaixo mostra como a fita da MTU é iniciada. Considere que à esquerda de X e à direita de w, naturalmente, existem infinitos símbolos brancos.

Ao iniciar com a fita assim, a MTU vai acrescentar um espaço para uma terceira informação: uma cadeia representando o estado atual da máquina X. Essa informação será fundamental para simular o funcionamento de X. Inicialmente, a fita teria a descrição do estado inicial q posicionada imediatamente antes da cadeia w assim:

O nosso objetivo será usar a fita para simular uma computação na máquina X. Portanto, deixaremos a informação do estado imediatamente antes do próximo símbolo a ser lido da cadeia w, similar à representação das IDs que criamos na seção 2.2 para as MTs. Assim, a região da fita que começou com a cadeia w será sucessivamente alterada para refletir o que X faria na sua fita. Portanto, em um momento qualquer da simulação a fita pode aparecer assim:

(52)

<fita-MTU, mas a ID da máquina X que a MTU está simulando na sua fita). O que a MTU irá fazer a partir de uma situação como essa é similar ao que fazemos com as IDs quando representamos uma computação em uma máquina de Turing. Porém, o processo na MTU será um tanto mais trabalhoso por conta das limitações da fita.

A cada passo da computação, a MTU irá se comportar assim:

1. Ela irá fazer voltar a cabeça da fita até a definição da máquina X no começo da área útil da fita. Dentro da definição de X, ela irá procurar o trecho que codifica a primeira transição.

2. Digamos que a transição encontrada (mesmo que codificada de outra forma) represente δ(qor, Aler) = (qdest, Aescr, M).

3. A MTU irá comparar se o estado de origem qor da transição é igual ao estado atual da máquina X, representado na figura como o trecho “q” da fita.

o Se forem distintos, ela vai procurar a próxima transição e volta ao passo 2.

4. Se os estados forem iguais, ela irá voltar à transição para ver qual o símbolo que ela precisa ler, que representamos antes como Aler. Em seguida, a MTU, vai comparar Aler com o símbolo atual da fita, que é o primeiro símbolo da região representada como “fita-direita”.

(53)

5. Se os símbolos forem iguais, então a MTU achou a transição a ser realizada na máquina X. Assim, a MTU vai voltar na fita para encontrar os resultados da transição, que são: (qdest, Aescr, M).

6. A MTU avança na fita para mudar o estado atual de X, que passará de q para qdest.

7. A MTU vai mudar o símbolo atual de X, que passará de A para Aescr.

8. A MTU vai deslocar o estado atual (qdest) uma posição para a esquerda (ficando a duas posições de distância de Aescr) ou uma posição para a direita (ficando depois do símbolo Aescr), dependendo do valor M (que pode ser E ou D).

Esse processo se repete enquanto a MTU encontrar, na descrição de X, alguma transição válida para realizar. Se, em algum momento, a MTU não achar uma transição, a MTU irá considerar que X parou. Nesse momento, a MTU irá procurar, na sua fita, o estado de X. Se for um estado de aceitação, a MTU aceita a cadeia w (indo para o seu estado de aceitação), senão ela rejeita. Dessa forma, ela dará a mesma resposta que X daria, como desejado.

(54)

Na próxima seção, usaremos a idéia da MTU para provar outro resultado interessante sobre as MTs.

3.2 O Problema da Parada

Vamos começar esta seção falando de uma característica da MTU que criamos antes. O que acontece se a entrada <X,w> descrever uma situação em que a máquina X entra em loop infinito? A MTU vai aceitar ou rejeitar? Como, nesse caso, a MTU apenas simula o comportamento de X (ao receber a cadeia w), vai acontecer com ela exatamente o que aconteceria com X: a MTU vai entrar em loop infinito!

Portanto, podemos descrever de maneira informal o comportamento da MTU assim:

Falar que ela pode entrar em loop...

Explicar o problema da parada (da aceitação?)...

A situação em que a MTU entra em loop não é exatamente um “resultado” que ela retorna, mas é um caso em que ela fica processando indefinidamente e não retorna nenhum resultado (como explicamos na seção 2.2 deste volume). Na verdade, os únicos resultados que desejamos obter da MTU (ou de qualquer MT) são apenas um dos dois: ACEITA ou REJEITA.

A grande questão que queremos discutir nessa seção é se é possível construir alguma MTU que sempre retorne um desses resultados e que nunca entre em loop. Construída da maneira que explicamos na seção anterior, realmente a MTU pode entrar em loop infinito, mas talvez exista outra maneira de construir uma MTU melhorada em que isso não aconteça.

Ao receber uma entrada <<X>,w>, a MTU: • Aceita, se X aceita w

• Rejeita, se X rejeita w

(55)

Para construir essa MTU melhorada, seria preciso lidar com o chamado Problema da Parada:

“Dada uma máquina de Turing X e uma cadeia w, identificar se X vai parar (ou

se vai entrar em loop infinito) ao receber a cadeia w”.

Se existir algum algoritmo (ou uma MT) para resolver esse problema, então podemos construir a MTU melhorada usando esse algoritmo como parte dela. A idéia para fazer essa nova MTU seria a seguinte: primeiro, ela testaria se a entrada <X,w> vai parar. Se a resposta for “sim”, ela simularia normalmente a entrada (seguindo a idéia que ensinamos na seção anterior). Se for “não”, ela rejeitaria diretamente essa entrada, sem simular nada.

Veja, que, na verdade, estamos mostrando que as duas questões abaixo estão interligadas:

• Será que temos como construir uma MTU melhorada que nunca entra em loop?

• Será que temos como prever que uma MT vai entrar em loop antes mesmo de simulá-la? (O problema da parada tem solução?)

Se encontrarmos a resposta de uma das duas questões, automaticamente estaremos encontrando a resposta da outra. Se existir uma máquina que decide o problema da parada, então existe uma MTU melhorada que nunca entra em loop e vice-versa. E se não existir uma máquina que decide o problema da parada, também não existe a MTU melhorada!

Infelizmente, não existe solução para o problema da parada e, portanto, a resposta para ambas as perguntas acima é NÃO. O restante desta seção será dedicado a provar isso. Mas como ambas as perguntas são interligadas, vamos provar apenas a primeira delas: vamos provar que não existe a tal “MTU melhorada” que nunca entra em loop!

Referências

Documentos relacionados

244 Chaves &amp; Vendramim Considerando-se os resultados obtidos, verifica-se que, embora tenha ocomdo efeito das cultivares sobre a preferência para oviposição (com chance

Se o seu livro Nação crioula desenha os contornos dessa Angola no espaço histórico colonial, o livro Es- tação das chuvas define a identidade angolana através da personagem

Para atender a demanda, o Curso Superior de Tecnologia em Estética e Cosmética – maquiagem profissional contempla as áreas de saúde, beleza, moda, maquiagem

Gramáticas Irrestritas A Máquina de Turing Universal MT e Funções Numéricas [4] A Tese de Church-Turing MTU. A

Algo importante que devemos antentar é que, quando usamos Máquinas de Turing na definição de algoritmos, não estamos dizendo a Máquina de Turing é o formalismo mais conveniente para

(B) Trata-se de afirmativas que compõem definições acerca do Drama como método de ensino do teatro, a partir.. de pesquisas realizadas por

Não vamos alterar compo- nentes da definição da máquina de Turing não determinística, assim como fizemos com a definição da máquina de Turing determinística de uma única fita

A Visão que temos para o Projecto “Melhor Eucalipto” é que ele contribua para a partilha do conhecimento técnico e alcançar os benefícios que resultam de uma floresta gerida