Esse é um desafio de policiais e ladrões , baseado na definição de idiomas e na comprovação de que eles estão completos em Turing.
Este é o tópico dos policiais. A discussão dos ladrões está aqui .
Policiais
Como policial, você preparará duas coisas:
Uma especificação formal de uma linguagem de programação ou outro sistema computacional. (Os sistemas computacionais são definidos abaixo.)
Uma prova de que seu sistema está completo com Turing, de acordo com a definição um pouco rigorosa abaixo.
Você publicará sua especificação do seu idioma, e os ladrões tentarão "decifrá-lo", comprovando sua integridade em Turing. Se o seu envio não for quebrado dentro de uma semana, você pode marcá-lo como seguro e postar sua prova. (Sua resposta pode ser invalidada se alguém encontrar uma falha na sua prova, a menos que você possa corrigi-la.)
Este é um concurso de popularidade , portanto, o vencedor será a resposta que tem mais votos e que não está rachada ou invalidada. O desafio é aberto - não aceitarei uma resposta.
Para esse desafio, um sistema computacional será definido como quatro coisas:
Um "conjunto de programas"
P
. Este será um conjunto infinitamente contável, por exemplo, seqüências de caracteres, números inteiros, árvores binárias, configurações de pixels em uma grade etc. (Mas veja a restrição técnica abaixo).Um "conjunto de entrada"
I
, que também será um conjunto infinitamente contável e não precisará ser o mesmo conjunto queP
(embora possa ser).Um "conjunto de saída"
O
, que da mesma forma será um conjunto infinitamente contável e pode ou não ser o mesmo queP
ouI
A, procedimento mecanicista determinística para a produção de uma saída
o
de programap
e de entradai
, ondep
,i
eo
são membros doP
,I
eO
respectivamente. Este procedimento deve ser tal que possa, em princípio, ser implementado em uma máquina de Turing ou outro modelo abstrato de computação. Obviamente, o procedimento pode não ser interrompido, dependendo do programa e de sua entrada.
Os conjuntos P
, I
e O
deve ser tal que você pode expressar-los como cordas de uma maneira computável. (Para a maioria das escolhas sensatas, isso não importa; essa regra existe para impedir que você escolha conjuntos estranhos, como o conjunto de máquinas de Turing que não param.)
A integridade de Turing será definida da seguinte forma:
- Para qualquer função parcial computável
f
deI
atéO
, existe um programap
emP
que dadop
e entradai
, a saída éf(i)
sef(i)
tiver um valor. (Caso contrário, o programa não será interrompido.)
A palavra "computável" na definição acima significa "pode ser calculada usando uma máquina de Turing".
Observe que nem a regra 110 nem o tag cíclico bit a bit são Turing-completos por esta definição, porque eles não têm a estrutura de entrada-saída necessária. O cálculo Lambda é Turing completo, desde que definamos I
e O
sejam os números da Igreja . (Não é Turing-completo se usarmos I
e formos O
expressões lambda em geral.)
Observe que você não precisa fornecer uma implementação do seu idioma, mas pode incluir um na sua resposta, se quiser. No entanto, você não deve confiar na implementação para definir o idioma de forma alguma - a especificação deve ser completa em si mesma e, se houver uma contradição entre a especificação e a implementação, isso deve ser tratado como um bug na implementação.
Respostas:
Aritmética com os olhos vendados
Possivelmente uma linguagem bastante fácil para começar, relativamente falando. (Existem limites para a dificuldade de uma linguagem que posso tornar, porque tenho que provar que estou me completando!)
Para esse idioma, o conjunto de programas é o conjunto de programas aritméticos com os olhos vendados, conforme indicado na seção "programa" abaixo, o conjunto de entrada é o conjunto de números inteiros positivos e o conjunto de saída é o conjunto de números inteiros (o conjunto inteiro, não apenas números inteiros positivos).
Essa linguagem é bastante interessante - talvez até praticamente útil - porque tem uma falta total ou parcial de fluxo de controle, sendo inteiramente baseada em cálculos em números que você não pode ver. Isso o torna potencialmente útil como uma linguagem para implementar programas dentro de sistemas de criptografia homomórfica .
Especificação
Aritmética com os olhos vendados é uma linguagem de programação esotérica com as seguintes especificações:
Armazenamento de dados
O estado de um programa aritmético de olhos vendados em execução consiste em seis variáveis, cada uma das quais pode armazenar um número inteiro. (Não há limites para o quão grande ou pequena estes números inteiros pode obter, em particular, eles podem ir negativo.) As variáveis são chamados
a
,b
,c
,d
,e
, ei
.No início do programa,
a
ae
inclusiva são cada inicializado a 0, ei
é inicializado para um inteiro positivo tirado de entrada do usuário. (Se nenhuma entrada estiver disponível,i
será inicializada como 1.)Se o programa interromper a execução (isso só pode ocorrer devido à divisão por zero), o valor
i
imediatamente antes da tentativa da divisão será usado como saída do programa.Programa
Um programa aritmético com os olhos vendados é uma lista de comandos, cada um com uma das seguintes formas (em que v pode ser substituído por qualquer nome de variável, potencialmente um nome diferente cada vez que é usado):
=
v+
v=
v-
v=
v*
v=
v/
vObserve que cada operando dos comandos deve ser uma variável; esse idioma não permite o uso de números inteiros literais.
A execução do programa é executada executando cada um dos comandos em sequência e, em seguida, retornando ao início e continuando a executar os comandos em sequência novamente, ad infinitum (ou até que haja uma tentativa de dividir por zero, o que encerra o programa) .
Cada comando tem a mesma semântica que você esperaria da notação, que não é diferente da usada pelas linguagens de programação mais práticas: são tomados os valores da segunda e terceira variáveis mencionadas no comando, uma operação aritmética (adicionar / subtrair / multiplicar / dividir respectivamente para as quatro formas de comando) é aplicado a elas e o valor resultante armazenado na primeira variável. Divisão aqui é divisão inteira, arredondando para 0.
Não há nenhum tipo de fluxo de controle além da saída do programa; os comandos sempre circulam em seqüência, até que uma divisão por zero (se houver) ocorra e finalize o programa. Em particular, não há como ler diretamente variáveis, apenas para usá-las como fonte de cálculos cujos resultados afetam os valores atribuídos a outras variáveis.
fonte
i
modo que o número do estado - que sempre será "interrompido" - não faça parte da saída), mas está perto o suficiente para que eu não marque isso como seguro, pois você claramente obteria uma rachadura completa com tempo suficiente e esclarecimentos suficientes das regras. Não quero vencer este desafio em termos técnicos.