Universidade Tecnológica Federal do Paraná Professor Murilo V. G. da Silva Notas de aula – Teoria da Computação (Aula 05) Conteúdos da Aula 05: [HMU01: cap.8] [SIP06: cap 3][ABA06: 1.1 e 1.2] [PAP94 2.6] 10. A Máquina de Turing Como dissemos no inı́cio do curso estamos em busca de respostas matemáticas precisas para as seguintes perguntas sobre os fundamentos da computação: (1) O que é um algoritmo? (2) O que é um computador? (3) O que é um problema computacional? A resposta para a pergunta (3) é relativamente simples: linguagens são objetos matemáticos adequados para modelar problemas computacionais. Para citar dois exemplos já vistos anteriormente, o problema de testar se um número é múltiplo de 3 pode ser modelado pela linguagem L3 = {w ; N (w) é um múltiplo de 3} e o problema de testar a primalidade de um número pode ser modelado pela linguagem Lp = {w ; N (w) é um número primo}. A idéia central é que são precisamente as strings de L3 que incorporam a propriedade “ser divisı́vel por 3” e são precisamente as strings que não estão em L3 que incorporam a propriedade “não ser divisı́vel por 3”. Algo análogo pode ser dito sobre a linguagem Lp com relação a primalidade. Uma simplificação que estamos fazendo aqui é que sempre estamos lidando com problemas para os quais a resposta é sim ou não. Estes problemas são conhecidos como problemas de decisão. Nem todo problema computacional é um problema de decisão. Um exemplo é o problema de caminho mı́nimo em grafos: dado uma tripla (G, u, v), onde G é um grafo e u, v são vértices de G, queremos encontrar o menor caminho entre u e v. A resposta para este problema é um caminho em G (ou seja, o objeto matemático que é a resposta para o problema é uma sequência de vértices de G). Outro exemplo é o problema de multiplicar dois números inteiros a e b. A resposta para este problema também não do tipo sim ou não, mais precisamente, a resposta é número inteiro ab. Mais adiante no curso lidaremos com tais problemas, mas já adiantamos que o fato de estarmos nos focando agora em problemas de decisão não é algo limitante e, de fato, mesmo estudando problemas de decisão já seremos capazes de explorar com detalhes os fundamentos e os limites da computação. Resolver um problema computacional pode ser visto como apresentar um algoritmo que determine se uma string pertence ou não pertence a uma linguagem. Dos dois exemplos citados acima, vimos que DFAs são capazes de resolver o problema da divisibilidade por 3 (Lista de Exercı́cios 2), mas por outro lado não são capazes de fazer teste de primalidade. Embora não tenhamos explorado PDAs a fundo, até mesmo eles não são capazes de fazer testes de primalidade. Entretanto sabemos que é fácil escrever um algoritmo em nossa linguagem de programação favorita que teste se um dado número é primo ou não. Com isso, fica claro que DFAs e PDAs não são modelos matemáticos capazes de capturar tudo o que um algoritmo pode realizar. Veremos agora um modelo matemático que captura não somente o conceito de algoritmo, respondendo a pergunta (1) do inı́cio desta seção, mas que nos permitá adiante responder também a pergunta (2). O modelo que veremos, chamado de Máquina de Turing, é semelhante a um DFA adicionado de uma fita de dados. A Figura 1 ilustra abstratamente o funcionamento de um DFA, um PDA e uma Máquina de Turing. x⇒ DFA ⇒ SIM/NAO x⇒ ⇒ PDA .. . x⇒ SIM/NAO ... B B B ⇒ MT B B B B B B SIM/NAO B B ... B B B B Figura 1: Visão abstrata de um DFA, de um PDA e de uma Máquina de Turing tomando a string x como entrada. A Máquina de Turing é essencialmente um DFA com uma fita contendo posições de memória. A máquina pode ler/escrever um sı́mbolo na fita e mover-se para a direita, para a esquerda, ou continuar acessando a mesma posição da fita. 1 A representação vista na Figura 1 é bastante útil para colocar Máquinas de Turing em perspectiva e permitir compará-la com modelos que vimos anteriormente neste curso, mas tal representação tem um pequeno detalhe que difere da definição que veremos a seguir. Por uma questão de simplicidade, na nossa definição de Máquina de Turing vamos assumir que a string de entrada já se encontra na fita de dados. Na realidade, existem algumas variações na maneira como Máquinas de Turing são definidas na literatura, inclusive diferenças que são aparentemente mais significativas, como possuir várias fitas de dados ou poder acessar mais de uma posição da fita de cada vez, mas todas estas variantes acabam tendo o mesmo poder computacional. Uma Máquina de Turing (MT) é uma 7-tupla M = (Q, Σ, Γ, δ, q0 , B, F ), onde: • Q é o conjunto finito de estados • Σ é o alfabeto de entrada. • Γ é o alfabeto da fita. • δ : (Q \ F ) × Γ → Q × Γ × D, onde D = {L, R, S}. • q0 é o estado inicial • B é o sı́mbolo especial chamado de sı́mbolo branco. • F ⊆ Q é o conjunto de estados finais. Figura 2: Alan Turing De agora em diante no curso, exceto quando explicitamente dito o contrário, vamos assumir que Σ é sempre o conjunto {0, 1}. Como já dissemos, vamos assumir que a string x de entrada no inı́cio da computação encontrase localizada na fita. Isso é possı́vel, pois teremos habilidade de nos movimentar a vontade na fita de memória da máquina sem descartar informação, o que não era com PDAs, por exemplo. Assumir que a string de entrada encontra-se na fita não é particularmente essencial, mas isso simplifica um pouco a nossa definição da função δ (lembre que o domı́nio da função δ de PDAs era uma tripla (estado, sı́mbolo, sı́mbolo) e agora o domı́nio da função δ de MTs é apenas um par (estado, sı́mbolo). A idéia é que a cada momento a máquina estará em um determinado estado e terá acesso a uma posição especı́fica da fita e, em tal situação, diremos que a cabeça de leitura da máquina está escaneando esta posição especı́fica da fita. Ao interpretarmos de δ(q, X) como uma função que retorna (q 0 , X 0 , d), estamos dizendo que se a máquina estiver no q e estiver com o sı́mbolo X sendo escaneado na fita, então a máquina muda para o estado q 0 , sobreescreve X na fita por X 0 e passa a escanear a posição a esquerda da fita quando d = L, ou a posição a direita da fita quando d = R, ou continua escaneando a mesma posição da fita quando q = S. Se a string de entrada é x = x1 x2 ...xn , no inı́cio da computação da MT, então vamos assumir que a cabeça de leitura estará posicionada no primeiro sı́mbolo da string, ou seja, em x1 . Além disso, por definição todos os demais sı́mbolos da fita (antes de x1 depois de xn ) são sı́mbolos B. A Figura 3 exemplifica isso. Máquina de Estados ... B B B x1 x2 B. . . B xn B B B . . . Figura 3: Máquina de Turing escaneando o primeiro sı́mbolo da string x = x1 x2 ...xn armazenada na fita. Observe que os conceitos de fita e de cabeça de leitura da máquina não estão aparentes na definição matemática da MT (por definição matemática queremos dizer a 7-tupla M = (Q, Σ, Γ, δ, q0 , B, F )). A definição por si só trata-se apenas de conjuntos, elementos e uma função “amarrando” estes conjuntos e elementos de alguma maneira especı́fica. Estes conceitos de fita e cabeça de leitura são intuições do que seria um objeto fı́sico que o modelo matemático descreve. Um ponto muito importante da Máquina de Turing é que o objeto fı́sico que temos em mente é extremamente simples. Trata-se basicamente de uma máquina de estados com uma fita de memória. Com isso, o modelo matemático que o descreve por completo acaba sendo extremamente simples. 2 Alguns fı́sicos gostam de brincar enunciando a seguinte frase: “considere uma vaca esférica no vácuo”. Isso seria um exemplo de um objeto exageradamente simples e em condições ideais. A idéia de um objeto simples como uma máquina de estados adicionada de uma fita de dados não deixa de parecer com a vaca esférica no vácuo dos cientistas da computação e, de fato, um dos atrativos de um objeto idealizado assim é a sua simplicidade. Mas o que torna este objeto idealizado realmente útil não é apenas a sua simplicidade, mas sim o fato de que ele é capaz de resolver precisamente o mesmo conjunto de problemas que qualquer computador atual é capaz de resolver. Na realidade, o consenso cientı́fico na área, conhecido como Tese de Church-Turing, é que não deve ser possı́vel construir um objeto consistente com as leis conhecidas da natureza que seja capaz de computar algo que uma Máquina de Turing não seja capaz de computar. Veremos mais sobre isso adiante. O funcionamento de uma Máquina de Turing Mencionamos que MTs são DFAs com uma fita de dados. A rigor, isso não é exatamente preciso por um mı́nimo detalhe: a função δ pode não estar definida em algumas situações. Isso também acontecia em NFAs, mas trataremos este caso de maneira diferente, pois a idéia é que MTs, ao contrário de NFAs, são modelos completamente determinı́sticos. Para MTs, Caso a função δ não esteja definida em um elemento de Q × Γ, diremos que a MT finaliza sua execução, e neste caso diremos que a MT para. Um ponto importante é que a ideia da máquina parar será visto como um passo puramente determinı́stico e não como um ramo de alguma computação possı́vel que que não chegou ao fim, como era o caso de DFAs. Por conta disso não vamos usar o termo “morre” em MTs. Vamos reservar o termo “morre” para MTs não determinı́sticas que definirimos na próxima aula em que o conceito de morrer terá uma interpretação semelhante ao conceito visto em NFAs. Mais precisamente, o comportamento da MT M = (Q, Σ, Γ, δ, q0 , B, F ) é determinı́stico, pois cada passo, ou seja, cada aplicação da função δ(q, X) sempre caı́mos em um dos dois casos: (1) A função δ é definida em (q, X), caso em que o comportamento da MT é unicamente determinado pela tripla de Q × Γ × D que a função δ retorna e portanto a máquina não tem escolhas a fazer; (2) A função δ não é definida em (q, X), caso em que o comportamento da MT também é unicamente determinado, pois a máquina só tem uma escolha, que é parar sua execução. Adiante veremos que o estado em que MT parou (final ou não final) vai definir se M aceitou ou não a string de entrada. Diagrama de estados de uma Máquina de Turing Podemos representar uma MT usando um diagrama de maneira semelhante aos autômatos vistos anteriormente neste curso. Na Figura 4, apresentamos um exemplo de um diagrama de uma MT. Ainda não definimos o que significa a linguagem de uma MT, mas observe que as únicas strigns que fazem a MT da Figura 4 atingir o estado final são as strings que pertencem a linguagem L = {0n 1n ; n ≥ 1}. Y /Y → 0/0→ start q0 0/X → q1 Y /Y ← 0/0← 1/Y ← X/X → Y /Y → q3 B/B → q4 Y /Y → Figura 4: Diagrama de uma Máquina de Turing. 3 q2 Computando com uma Máquina de Turing A Descrição Instantânea (ID) de uma MT é uma string X1 X2 ...Xi−1 qXi Xi+1 ...Xn . Esta string descreve a seguinte situação: a fita contém a string X1 ...Xn enquanto a máquina está escaneando a posição Xi e encontrase no estado q. A fita contém uma sequência infinita de sı́mbolos B à esquqerda de X1 e a direita de XN . Note também que a quantidade de sı́mbolos X1 , ..., XN é finita (pois X1 X2 ...Xn é uma string, e strings são finitas). Note também que alguns sı́mbolos Xi podem ser eventualmente iguais a B. Vamos definir agora os sı́mbolos `M e `∗M . Dada uma TM M = (Q, Σ, Γ, δ, q0 , B, F ), se δ(q, Xi ) = (p, Y, L), então dizemos que X1 X2 ...Xi−1 qXi Xi+1 ...Xn `M X1 X2 ...Xi−2 pXi−1 Y Xi+1 ...Xn . Note que a definição acima reflete um passo da computação da MT e o movimento para a esquerda. Entretanto há duas exceções nesta definição acima: • Se i = 1, então qX1 ...Xn `M pBY X2 ...Xn • Se i = n e Y = B, então X1 X2 ...Xn−1 qXn `M X1 X2 ...Xn−2 pXn−1 Exercı́cio 10.1: Defina o sı́mbolo `M no caso em que δ(q, Xi ) = (p, Y, R) e no caso em que δ(q, Xi ) = (p, Y, S). Linguagem de uma Máquina de Turing Dada uma MT M , a linguagem de M é L(M ) = {w ∈ Σ∗ ; q0 w `∗M αpβ, onde p ∈ F e α, β ∈ Γ∗ quaisquer}. Neste caso dizemos que M aceita as strings da linguagem L(M ), ou diremos que M aceita a linguagem L(M ). Se L é aceita por alguma MT, então a linguagem L é dita Recursivamente Enumerável. O conjunto das linguagens recursivamente enumeráveis é denotado por RE. A partir da maneira como definimos MTs, observe que temos algumas consequências importantes: • Como na computação de uma MT não existe o conceito de terminar de ler a string de entrada (diferentemente de DFAs e PDAs), existe a possibilidade de que a máquina continue computando indefinidamente em algumas circunstâncias, ou seja, a máquina pode ficar em “loop infinito”. • Uma vez que em nossa definição de MTs a função δ nunca é definida em um estado final (note que F é excluı́do do domı́nio de δ na definição da nossa MT), a máquina sempre para quando a string é aceita. Uma consequência disso é que se L ∈ RE, então existe uma MT M que para cada string w ∈ L, a máquina M aceita w e para. Observe que se um string w ∈ / L não é aceita por M isso pode significar duas coisas: M parou em um estado que não é final ou M ficou em loop infinito. • A nossa busca por uma definição matemática formal para um algoritmo é essencialmente uma busca por uma definição genérica do o que seja um procedimento determinı́stico que retorne a solução para qualquer instância de um dado problema em um número finito de passos. Com isso, essa possibilidade das MTs continuarem computando indefinidamente não parece desejável. Por hora vamos manter em aberto esta possibilidade de que MTs possam ser programadas para rodar indefinidamente, pois isso nos será útil adiante. O ponto chave é que dentre o conjunto de todas MTs, podemos querer nos restringir somente àquelas que, para qualquer que seja a entrada, sempre parem depois de um número finito de passos. A seguir vamos fazer exatamente isso: excluir MTs que nunca param do nosso conceito de algoritmo. Algoritmo como sinônimo de MT que sempre para A partir de agora passaremos usar os termos MT que sempre para e Algoritmo como sinônimos. Entretanto, é importante observar que quando usarmos o apenas o termo “Máquina de Turing”, sem especificar que ela sempre para, não necessariamente estaremos nos referindo a um algoritmo. Seja M uma MT que sempre para. Se L = L(M ), dizemos que M decide L. Se existe MT que decide uma dada linguagem L, dizemos que L é uma Linguagem Recursiva. Note que quando L é decidida, a máquina M tal que L = L(M ) por definição tem a propriedade de sempre parar, o que não era uma restrição para linguagens aceitas por alguma MT. Denotamos o conjunto das linguagens recursivas por R. Quando uma MT para com uma determinada string que não é aceita, diremos que a MT rejeitou a string de entrada. Em outras palavras, um algoritmo vai sempre aceitar ou rejeitar uma entrada, e nunca ficar em loop infinito. Exercı́cio 10.2: Mostre que R ⊆ RE. Pergunta 10.1: Será que existe uma linguagem que esteja em RE, mas que não esteja em R? Ou ainda, será que existe alguma linguagem qualquer (independente de estar ou não em RE) que não esteja contida em R? Em outras palavras, será que existe um problema que não admita um algoritmo que o decida? 4 11. A Tese de Church-Turing Desde o inı́cio do curso exploramos o conceito de modelos matemáticos equivalentes. Por exemplo, DFAs e NFAs são equivalentes, pois dada uma linguagem L aceita por um NFA, é possı́vel construir um DFA que aceita a mesma linguagem L. Assim como dada uma linguagem L0 aceita por um DF A, é possı́vel construir um N F A que aceita L0 . Esta idéia de equivalência de modelos é central em teoria da computação. Durante a primeira metade do século XX muitos matemáticos estavam a procura de um modelo matemático para descrever algoritmos (na época era bastante comum usar a expressão “procedimento efetivo” ao invés de algoritmo) e vários modelos foram sendo propostos. Aos poucos, foi se percebendo que estes modelos eram todos equivalentes. Estes trabalhos eram puramente teóricos e o objetivo a não era necessariamente propor modelos matemáticos com alguma correspondência com dispositivos fı́sicos. O contexto matemático exato em que estas teorias começaram a ser desenvovidas está fora do escopo deste curso, mas, a grosso modo, o que acontecia é que alguns matemáticos começaram a ver o enunciado de um teorema como uma sequência de sı́mbolos. Somado a isso, também era possı́vel ver axiomas (fatos básicos assumidos verdadeiros) como sequências de sı́mbolos e regras de inferência (regras para se obter novos fatos verdadeiros a partir de fatos previamente verdadeiros) como sequência de sı́mbolos representando regras ditando como sı́mbolos podem ser manipulados. Isso motivou o matemático David Hilbert a desafiar a comunidade matemática em 1928 a encontrar um algoritmo que tome como entrada uma afirmação matemática e que responda sim, se a afirmação é verdadeira, ou seja, é um teorema, ou não se a afirmação é falsa1 . Esse problema é conhecido como Entscheidungsproblem (problema da decisão, em alemão). Ou seja, o que os matemáticos queriam era atingir o objetivo nada modesto de encontrar o algoritmo que dada uma afirmação matemática, responda se ela é verdadeira ou falsa2 . Em 1936, primeiramente Alonzo Church e logo em seguida Alan Turing provaram que tal algoritmo não existe. O ponto chave é que para se provar tal resultado, é necessário dar uma definição precisa do que seja um algoritmo. Alonzo Church usou um formalismo matemático chamado cálculo λ e Alan Turing criou seu formalismo matemático, que hoje em dia é chamado de Máquina de Turing. Os dois modelos são equivalentes, mas a vantagem do modelo de Turing era a sua simplicidade e intuitividade, de maneira que ele tinha essa interpretação “fı́sica”. Em seu trabalho Turing também mostrou que seu modelo tinha uma propriedade importantı́ssima conhecida com universalidade. Veremos adiante que a descoberta desta propriedade marca o inı́cio do que entendemos como computador e computação hoje em dia. O primeiro teorema que enunciaremos nesta aula diz que Máquinas de Turing são equivalentes a algoritmos como conhecemos hoje em dia. A prova não envolve nenhum conceito complicado, mas ela é longa e técnica, e portanto não é muito iluminadora e está fora do escopo do curso. O aluno curioso pode ler a prova na seção 2.6 do livro [PAP94]. Para enunciar o teorema vamos definir um modelo matemático equivalente a programas escritos em assembly para computadores atuais. Lembramos, é claro, que qualquer programa escrito atualmente em uma linguagem de programação de alto nı́vel pode ser expressa com um programa em assembly (o trabalho de um compilador é essencialmente fazer esta conversão). Programas em Assembly Um Programa Assembly (PA) é uma sequência finita Π = π1 , π2 , ..., πn . Cada elemento desta sequência é chamado de instrução. Cada instrução πi pode ser de duas formas: • πi é um par (a, b) • πi é um elemento a Os elementos a e b são elementos dos seguintes conjuntos: • a ∈ {add, sub, read, store, load, half, jump, jpos, jzero, jneg, zero} • b ∈ {j,ˆj}, onde j é um inteiro. Além disso, há ainda as seguintes restrições sobre os tipos de intruções válidas: • Se πi é um elemento a, então a ∈ {halt, half} • Se b =ˆj, então b ∈ {read, store} 1 Podemos tanto imaginar que o algoritmo toma juntamente os axiomas e as regras de inferência como entrada, quanto imaginar que estes elementos são algo fixo conhecido a priori. 2 Na realidade, o matemático Gottfried Leibniz também já havia pensado sobre este mesmo problema no século XVII, embora na época a matemática não estava tão avançada para que esta pergunta pudesse ser formulada precisamente. 5 Abaixo exemplos de uma sequência de instruções válidas: add 33 read 10 read ˆ10 half store 12 halt Assim como fitas e cabeças de leitura são interpretações fı́sicas de MTs, a semântica de cada uma destas instruções (por exemplo, a instrução half divide por 2 o valor contido em algum registrador padrão do processador do computador) também é algo externo a definição matemática do programa em assemby. Obviamente o termo semântica, em última análise, se refere a um processo fı́sico ocorrendo no processador. Deixamos como exercı́cio para o aluno ler no livro [PAP94] a semântica de cada uma das instruções válidas em um PA. Sabemos que podemos criar Programas Assembly não apenas para problemas cuja resposta seja sim ou não, mas também para realizar uma série de outras tarefas. Na realidade, MTs também são bem versáteis e podem lidar com outros tipos de problemas. Mas como estamos agora nos restringindo a problemas do tipo sim ou não, vamos definir o que é a linguagem de um determinado Programa Assembly Π. Antes de qualquer coisa precisamos ler a entrada do programa. Dado um Programa Assembly, vamos assumir que o i-ésimo bit da string de entrada x = x1 x2 ...xn é acessı́vel usando a instrução read i. Como já mencionamos, para os nossos propósitos não precisamos saber o significado exato das instruções de um PA, mas a idéia geral é que dada uma entrada, o programa vai executar uma série de instruções e eventualmente executar a instrução halt para finalizar a execução. A idéia é que para indicar se o programa aceitou ou rejeitou a string de entrada, ele poderá “setar” um determinado bit para 0 ou 1. Isso é feito usando a instrução load i. A linguagem de um programa Π, denotada L(Π) é o conjunto de strings de entrada tal que a última vez que a instrução load i apareceu, o valor i é diferente de 0. Caso a última instrução load i tem o valor i = 0 ou nenhuma instrução do programa é do tipo load i, a entrada é rejeitada. Teorema 11.1: Para todo Programa Assembly Π, existe uma Máquina de Turing M tal que L(M ) = L(Π). Em outras palavras, para cada PA existe uma MT que resolve o mesmo problema. Como já mencionamos, a prova deste teorema pode ser vista na seção 2.6 do livro [PAP94]. A outra direção do enunciado do teorema também é verdade, ou seja, para cada MT existe um PA que resolve o mesmo problema, o que significa que os dois modelos de computação são equivalentes. Não apenas Programas Assembly, mas sim vários formalismos matemáticos são equivalentes a MTs. O seguinte teorema, que vamos enunciar de maneira informal aqui, ilustra alguns destes casos: Teorema 11.2: Os seguinte modelos são equivalentes a MTs: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) MT com múltiplas fitas; MT com uma fita infinita em apenas uma direção; MT em que a entrada esteja em uma fita “read only” e as demais fitas sejam “read-write”; MT com alfabetos com mais sı́mbolos; Cálculo λ; Funções µ-recursivas3 ; PDA com 2 pilhas; Linguagens de programação modernas (e.g., C, C++, Java); Modelo aTAM; Modelo de Circuitos Quânticos4 3 Cálculo λ, funções µ-recursivas, assim como vários outros formalismos matemáticos, são definições puramente matemáticas para algoritmos, sem intenção, a princı́pio, de ter correspondência com modelos fı́sicos que os possam ser de fato implementados 4 Tanto o modelo ATAM quanto o modelo de Circuitos Quânticos são modelos matemáticos correspondentes a objetos fı́sicos usados como substrato para implementar algoritmos. O modelo ATAM corresponde a utilização de moléculas baseadas em DNA para efetuar computação. O modelo de Circuitos Quânticos corresponde a utilização de objetos fı́sicos pequenos o suficiente de maneira que o processo de computação ocorra a partir da manipulação da informação quântica destes objetos. 6 Agora apresentamos o conceito mais fundamental de toda ciência da computação: Tese de Church-Turing (TCT) A Máquina de Turing captura o conceito de computação efetiva. Há duas interpretações para o que significa dizer que uma MT captura o conceito de computação efetiva. A primeira interpretação é da TCT como definição matemática a outra é como afirmação sobre o mundo fı́sico. Por definição matemática, vamos usar a seguinte analogia: imagine alguém dizendo que “a definição de função contı́nua usando epsilons e deltas como normalmente vemos em um curso de Cálculo captura o conceito de continuidade de funções”. Uma afirmação como esta acima pode ser debatida e algumas pessoas podem concordar e outras discordar, mas no fim ela é aceita por que ela é útil e funciona. Por funcionar queremos dizer que como não parece existir alguma função contı́nua que não possa ser expressa em termos da tradicional definição usando epsilons e deltas, então nós definimos funções contı́nuas desta maneira e funções não contı́nuas como funções que não podem ser expressas desta maneira. A afirmação de que algoritmos como concebemos hoje em dia, como um código escrito em C, define exatamente o que é um algoritmo (e portanto, pelo Teorema 2 uma Máquinas de Turing também definem o que é um algoritmo) é algo que é útil e faz sentido na prática. Algumas pessoas poderiam debater se existe ou não existe um formalismo matemático capaz de representar algo que reconheçamos como um algoritmo, mas que não pode ser expresso na forma como escrevemos algoritmos hoje em dia. Embora isso aparentemente seja algo infrutı́fero, ainda assim faz sentido para alguns debater esta questão. Por outro lado, interpretar o conceito de computação efetiva como uma afirmação sobre o mundo fı́sico, que é o que se entende atualmente por TCT, é bem mais interessante por eliminar debates infrutı́feros. Essencialmente, a TCT diz que qualquer objeto condizente com as leis da fı́sica pode ser simulado por uma Máquina de Turing. Aqui a palavra simulado tem um significado preciso: há uma relação de um para um “amarrando” o objeto fı́sico e seus possı́veis graus de movimento com o modelo matemático e suas possı́veis transições. Um ponto chave é que tal afirmação parece depender de sabermos quais são as leis finais da fı́sica, o que de fato não sabemos (por exemplo, atualmente não conseguimos conciliar a mecânica quântica com a teoria da relatividade), mas o que a ciência sempre faz é trabalhar com o que temos de melhor no momento. Nos últimos 80 anos, desde que a MT foi definida, a versão fı́sica da TCT foi ganhando força pela e atualmente é ortodoxia em ciência, em particular pelo entendimento crescente de como funciona a natureza. A grosso modo, a TCT hoje é ortodoxia por que quando descemos no nı́vel mais fundamental da matéria e estudamos como objetos se comportam, sabemos precisamente os tipos de graus de movimentos que objetos podem ter, pois eles são restringidos pelas leis da mecânica quântica. Somado a isso, sabemos também que existe uma relação de um para um entre qualquer objeto concebı́vel e um circuitos quântico5 e sabemos pelo Teorema 11.2 que existe também uma relação de um para um de circuitos quânticos com Máquinas de Turing. A vantagem da versão fı́sica da TCT ao contrário da versão matemática é que ela é uma afirmação cientı́fica que pode ser refutada empiricamente, como qualquer afirmação cientı́fica atual (afirmações que não podem ser refutadas não são de interesse da ciência). Essa visão pode ser concisamente expressa pelas duas seguintes citações de pesquisadores da área: One can get into endless debates about what exactly the Church-Turing Thesis means. Personally, though, I’ve always preferred the version that takes it to be a falsifiable empirical claim, about what sorts of computational problems can be solved in the physical world. For that version has the enormous advantage of clarity: it makes it clear exactly what it would take to falsify the Church-Turing, namely, a revolution in physics. – Scott Aaronson Theory of computation is a theory of how you can use physical objects to represent abstract objects. Computers are a way to instantiate abstract objects and their relationships into physical objects and their motions. The important lesson of the universality of computation is that we can make a physical object that can simulate every physical process and the set of all possible motions of this object, defined by all possible programs in this computer, is in one to one correspondence with the set of all possible motions of anything. – David Deutsch 5 Isso vem da maneira como circuitos quânticos são definidos, assunto coberto em cursos de Computação Quântica. 7 Com relação ao Teorema 11.2, há mais um fato bastante importante a se destacar. Vamos enunciar isso de maneira informal no teorema abaixo: Teorema 11.3: Uma MT simula os modelos (1) a (9) do Teorema 11.2 com eficiência polinomial No enunciado do teorema acima não fomos claros no que queremos dizer com eficiência polinomial, mas alunos com fluência em projeto e análise de algoritmos intuitivamente entendem o que isso quer dizer: não é possı́vel definir nenhum algoritmo em um dos modelos (1) a (9) em que o número de passos no modelo seja exponencialmente menor do que o número de passos que a MT correspondente levaria. Veja que só incluı́mos os itens (1) a (9) e deixamos o item (10) de fora do enunciado do Teorema 11.3. O fato é que conjectura-se que não seja verdade que MTs simulem Circuitos Quânticos com eficiência polinomial para qualquer problema. O modelo de Circuitos Quânticos é até o momento o único modelo matemático com contrapartida em objetos fı́sicos para o qual conjectura-se tal fato. O que ocorre é que atualmente existem algoritmos quânticos para alguns problemas que são exponencialmente mais eficientes do que os melhores algoritmos clássicos conhecidos (por algoritmos clássicos queremos dizer MTs ou qualquer um dos modelos (1) a (9), por exemplo) para os mesmos problemas. Entretanto, provar matematicamente que de fato não existam algoritmos polinomiais ainda não descobertos para tais problemas é uma questão em aberto, mas atualmente trabalha-se com a hipótese de que o modelo de computação quântica é exponencialmente mais eficiente do que o modelo clássico para alguns problemas especı́ficos. Esta conjectura é conhecida como a conjectura de que P 6= BQP. Observe que mesmo que prove-se tal conjectura e conclua-se que o modelo de computação quântica é inerentemente mais eficiente que o modelo de MTs, a Tese de Church-Turing continua completamente intacta, pois em termos do que se é possı́vel computar (e não eficiência de tais tarefas) computadores quânticos e clássicos são equivalentes. Em outras palavras, o conjunto de problemas que podem ser resovidos por computadores quânticos é precisamente o conjunto das linguagens recursivas. Ainda assim, atualmente o interesse na construção de computadores quânticos é enorme, em particular por conta da importância de vários problemas computacionais que eles possivelmente poderiam resolver de maneira exponencialmente mais rápida do que os computadores atuais. 8