Qual é o conjunto mínimo de recursos / estruturas de linguagem que o tornam completo em Turing?
Qual é o conjunto mínimo de recursos / estruturas de linguagem que o tornam completo em Turing?
Respostas:
Um tarpit de Turing é um tipo de linguagem de programação esotérica que se esforça para ser completa em Turing enquanto utiliza o mínimo de elementos possível. Brainfuck é talvez o tarpit mais conhecido, mas existem muitos.
Iota e Jot são linguagens funcionais com dois e três símbolos, respectivamente, com base no cálculo combinador SK (I) .
OISC ( One Instruction Set Computer ) indica um tipo de computação imperativa que requer apenas uma instrução de um ou mais argumentos, geralmente "subtraia e ramifique se for menor ou igual a zero" ou "subtraia e pule se pedir emprestado". O x86 MMU implementa a instrução anterior e, portanto, é Turing-completo.
Em geral, para que uma linguagem imperativa seja completa em Turing, ela precisa:
Uma forma de repetição condicional ou salto condicional (por exemplo while
, if
+ goto
)
Uma maneira de ler e escrever alguma forma de armazenamento (por exemplo, variáveis, fita)
Para que uma linguagem funcional baseada no cálculo lambda seja TC, ela precisa:
A capacidade de abstrair funções sobre argumentos (por exemplo, abstração lambda, cotação)
A capacidade de aplicar funções a argumentos (por exemplo, redução)
É claro que existem outras maneiras de ver a computação, mas esses são modelos comuns para tarpits de Turing. Observe que computadores reais não são máquinas de Turing universais porque não possuem armazenamento ilimitado. A rigor, eles são "máquinas de armazenamento limitado". Se você continuasse adicionando memória a eles, eles abordariam assintoticamente as máquinas de Turing no poder. No entanto, mesmo máquinas de armazenamento limitado e máquinas de estado finito são úteis para computação; eles simplesmente não são universais .
Estritamente falando, a E / S não é necessária para a integridade de Turing; O TC apenas afirma que um idioma pode calcular a função desejada, não que ele possa mostrar o resultado. Na prática, toda linguagem útil tem uma maneira de interagir com o mundo de alguma forma.
De um ponto de vista mais prático: se você pode traduzir todos os programas em um idioma completo de Turing para o seu idioma, então (tanto quanto eu sei), seu idioma deve estar completo de Turing. Portanto, se você quiser verificar se um idioma que você criou é completo em Turing, basta escrever um Brainf *** no compilador YourLanguage e provar / demonstrar que ele pode compilar todos os programas legais de BF.
Para esclarecer, quero dizer que, além de um intérprete para YourLanguage, você escreve um compilador (em qualquer idioma) que pode compilar qualquer programa BF para YourLanguage (mantendo a mesma semântica, é claro).
</sarcasm>
Um sistema só pode ser considerado como Turing completo se puder fazer qualquer coisa que uma máquina universal de Turing possa. Como se diz que a máquina universal de Turing é capaz de resolver qualquer função computável em um determinado período de tempo, os sistemas completos de Turing também podem, por extensão, fazê-lo.
Para verificar se algo está completo de Turing, veja se você pode implementar uma máquina de Turing dentro dela. Em outras palavras, verifique se ele pode simular o seguinte:
Estes são os verdadeiros requisitos mínimos para que um sistema seja considerado completo como Turing. Nada mais nada menos. Se ele não pode simular nada disso de alguma forma, não é Turing completo. Os métodos propostos por outras pessoas são apenas meios para o fim, pois existem vários sistemas completos de Turing que não possuem esses recursos.
Observe que não há maneira conhecida de realmente construir um verdadeiro sistema completo de Turing. Isso ocorre porque não há uma maneira conhecida de simular genuinamente a ilimitação da fita da máquina de Turing no espaço físico.
Uma linguagem de programação está completa se você puder fazer qualquer cálculo com ela. Não há apenas um conjunto de recursos que faz com que um idioma fique completo, então as respostas dizendo que você precisa de loops ou que você precisa de variáveis estão erradas, pois há idiomas que não têm mas estão completos.
Alan Turing criou a máquina de turing universal e, se você pode traduzir qualquer programa projetado para funcionar na máquina universal para rodar no seu idioma, também é Turing completo. Isso também funciona indiretamente, para que você possa dizer que o idioma X está completo, se todos os programas para o idioma completo Y puderem ser traduzidos para o X, pois todos os programas universais de máquinas de turismo podem ser traduzidos para um programa Y.
A complexidade do tempo, a complexidade do espaço, o formato fácil de entrada / saída e a escrita de qualquer programa não estão incluídos na equação, de modo que essa máquina pode teoricamente fazer todos os cálculos se os cálculos não forem interrompidos por perda de energia ou se a Terra for engolida pelo sol.
Geralmente, para provar a integridade do turing, eles fazem um intérprete para qualquer idioma comprovadamente completo, mas para que ele funcione, você precisa de meios de entrada e saída, duas coisas que realmente não são necessárias para que um idioma fique completo. É suficiente que seu programa possa alterar seu estado na inicialização e que você possa inspecionar a memória após a interrupção do programa.
Para criar uma linguagem bem-sucedida, é necessário mais do que completar a completude, e isso é verdade até mesmo para aumentar o tarpits. Eu não acho que BrainFuck teria sido popular sem ,
e .
.
Você não pode dizer se o loop será infinito ou parado.
Explicação: Dadas algumas entradas, é impossível dizer em todos os casos (usando outra máquina de Turing) se a coisa vai repetir-se infinitamente ou eventualmente parar, exceto executando-a (o que dá uma resposta se ela parar, mas não se loops!).
Isso significa que você precisa poder armazenar uma quantidade potencialmente ilimitada de dados de alguma forma - deve haver um equivalente à fita infinita, não importa quão complicada! (Caso contrário, há apenas um número finito de estados e você poderá verificar se já passou por esse estado anteriormente e eventualmente parar). Geralmente, as máquinas de Turing podem aumentar ou diminuir o tamanho de seu estado por alguns meios controláveis.
Como a máquina de Turing universal original da Turing tem um problema de parada insolúvel, sua própria máquina completa de Turing também deve ter um problema de parada insolúvel.
Os sistemas completos de Turing podem emular qualquer outro sistema completo de Turing, portanto, se você pode criar um emulador para algum sistema completo de Turing bem conhecido em seu sistema, isso prova que seu sistema também está completo.
Por exemplo, suponha que você queira provar que Snakes & Ladders está completo em Turing, considerando um quadro com um padrão de grade repetidamente infinito (com uma versão diferente no lado superior e esquerdo). Sabendo que a máquina Minsky de 2 contadores está completa em Turing (que possui 2 contadores ilimitados e 1 estado de um número finito), você pode construir uma placa equivalente em que as posições X e Y na grade sejam o valor atual dos 2 contadores e o caminho atual é o estado atual. Bang! Você acabou de provar que Snakes & Ladders está completo em Turing.
Uma condição necessária é um loop com uma contagem de iteração máxima que não é determinada antes da iteração ou recursão em que a profundidade máxima de recursão não é determinada com antecedência. Como exemplo, para ... nos ... loops, pois você os encontra em muitos idiomas mais novos, não é suficiente para tornar o idioma completo (mas eles terão outros meios). Observe que isso não significa número limitado de iterações ou profundidade de recursão limitada, mas que as iterações e a profundidade de recursão máximas devem ser calculadas com antecedência.
Por exemplo, a função Ackermann não pode ser calculada em um idioma sem esses recursos. Por outro lado, muitos softwares altamente complexos e úteis podem ser gravados sem a necessidade desses recursos.
Por outro lado, com todas as contagens de iterações e todas as profundidades de recursão calculadas adiante, não só pode ser decidido se um programa será interrompido ou não, mas também será interrompido.
Eu sei que essa não é a resposta formalmente correta, mas depois que você tirar o 'mínimo' de 'Turing-complete' e colocar 'prático' de volta onde ele pertence, você verá os recursos mais importantes que distinguem uma linguagem de programação de uma linguagem de marcação são
próximo vem
Para testar essas afirmações, comece com uma linguagem de marcação, por exemplo, HTML. poderíamos inventar um HTML + apenas com variáveis ou apenas condicionais (o MS fez isso com comentários condicionais) ou algum tipo de construção de loop (que na ausência de condicionais provavelmente acabaria como algo parecido <repeat n='4'>...</repeat>
). fazer qualquer uma dessas opções tornará o HTML + significativamente (?) mais poderoso que o HTML comum, mas ainda assim seria mais uma marcação do que uma linguagem de programação; com cada novo recurso, você o torna menos uma linguagem declarativa e mais imperativa.
a busca pela minimalidade na lógica e na programação com certeza é importante e interessante, mas se eu tivesse que ensinar a n00bies jovens ou velhos 'o que é programação' e 'como aprender a programar', dificilmente começaria com toda a amplitude e largura dos fundamentos teóricos da integralidade de Turing. toda a essência da culinária e da programação é fazer as coisas, na ordem certa, repetindo até ficar pronta, como sua mãe fez. isso resume tudo para mim.
então, novamente, eu nunca terminei meu CS.