O termo "perfeição de Turing" foi discutido em várias das aulas de ciência da computação que eu participei. No entanto, nunca tive uma noção intuitiva do que a integridade de Turing realmente exige. Encontrei essa pergunta, mas as respostas são um pouco mais matemáticas do que o que estou procurando.
Pegue uma linguagem de programação comum, como C ++, Python, Java ou Lisp. A que distância essas línguas estão de Turing não estar completa? Essas linguagens possuem recursos elementares que, se removidos, tornariam a linguagem não Turing completa? Ou você poderia alterar uma propriedade do idioma (por exemplo, tornar algo aleatório) e, ao fazer isso, tornar o idioma não Turing completo?
while
loops.Respostas:
Linguagens de programação comuns são muito firmemente concluídas em Turing, se você tiver uma visão idealizada de onde os programas podem usar uma grande quantidade arbitrária de memória. Normalmente, não há um único recurso que você possa isolar sem o qual o idioma não seria completo em Turing.
Intuitivamente falando, a integridade de Turing requer duas coisas:
malloc
,new
, etc. Mesmo alocação baseada em pilha é suficiente, desde que haja uma forma de objetos de acesso a qualquer distância do topo da pilha (apenas com alocação baseada em pilha e apenas acesso ao topo da pilha, você obtém apenas um autômato de empilhamento). Muitas formas mais fracas de manipulação de dados também são adequadas: por exemplo, em uma linguagem como Lisp ou Python, onde os números inteiros não têm tamanho limitado, as operações inteiras básicas por si só são suficientes para a integridade de Turing.if
oucase
/switch
) egoto
mais alguma forma de condicional são as três formas mais comuns, mas existem outras.Penso que a melhor maneira de entender o que torna uma linguagem completa em Turing é observar exemplos de linguagens poderosas, mas não completas em Turing. Vou dar dois exemplos que ilustram as duas famílias principais desses idiomas (exceto os que operam na memória limitada).
Considere uma linguagem imperativa com operações e matrizes inteiras, mas apenas para loops (
for i = 1 to n
ondei
não pode ser modificado durante o loop), não para loops arbitrários (while) e sem recursão. BlooP e versões anteriores do FORTRAN são exemplos. Nesse idioma, você só pode expressar funções recursivas primitivas - funções em que a quantidade de computação é limitada no tamanho da entrada. O idioma não está completo em Turing - não pode expressar funções recursivas arbitrárias - devido ao limite no tempo de computação.Uma linguagem funcional pode ser tornada não completa de Turing, restringindo a recursão por meio de um sistema de tipos que restringe todas as funções a serem encerradas. Se o sistema de tipos for decidível (ou seja, se for decidível se o programa está bem digitado), esse idioma não poderá ser concluído por Turing (porque o problema de parada é indecidível). Idiomas usados para a prova de teoremas, como Coq e Agda , são desse tipo.
Veja também O que Idris não pode fazer renunciando à totalidade de Turing?
Em uma nota lateral, os provadores de teoremas exigem que o usuário insira provas de término (ou seja, eles não os encontram). Assim, você poderia fazer um teste de teoremas com um sistema de tipos indecidíveis: se você receber uma prova correta, estará feliz, caso contrário, desistirá após um tempo. Mas não seria fácil de usar. A maioria dos provadores de teoremas tem um sistema de tipos decidível: você digita um termo e ele é aceito ou você recebe um erro de tipo de volta. O que os provadores de teoremas não têm é uma inferência de tipo decidível : se você digitar um termo com informações de tipo parcial e for rejeitado, não saberá se é porque o termo não pode ser digitado ou porque o mecanismo de inferência não era suficientemente inteligente.
fonte