O objetivo desse desafio é (eventualmente) gerar todos os programas de parada possíveis em um idioma de sua escolha. No início, isso pode parecer impossível, mas você pode fazer isso com uma escolha muito cuidadosa da ordem de execução.
Abaixo está um diagrama ASCII para ilustrar isso. Deixe as colunas representarem uma numeração de todos os programas possíveis (cada programa é um número finito de símbolos de um alfabeto finito). Deixe cada linha representar uma etapa singular na execução desse programa. Um X
representa a execução executada por esse programa naquele intervalo de tempo.
step# p1 p2 p3 p4 p5 p6
1 X X X X X X
2 X X X X X
3 X X X X
4 X X X X
5 X X X
6 X X
7 X X
8 X X
9 X X
∞ X X
Como você pode ver, os programas 2 e 4 não param. Se você os executasse um de cada vez, seu controlador ficaria preso no loop infinito que é o programa 2 e nunca produziria os programas 3 e além.
Em vez disso, você usa uma abordagem de encaixe . As letras representam uma possível ordem de execução para as primeiras 26 etapas. Os *
s são locais onde o programa foi interrompido e produzido. Os .
passos são ainda não executados.
step# p1 p2 p3 p4 p5 p6
1 A C F J N R V
2 B E I M Q * Z
3 D H * P U
4 G L T Y
5 K O X
6 * S .
7 W .
8 . .
9 . .
∞ . .
Requisitos para o idioma de destino
O idioma de destino (o que está sendo interpretado em paralelo) deve estar completo em Turing. Fora isso, pode ser qualquer idioma que seja completo em Turing, incluindo subconjuntos completos em Turing de idiomas muito maiores. Você também é livre para interpretar coisas como regras do sistema de etiquetas cíclicas. Você também pode criar um idioma para testar, desde que possa mostrar por que o Turing está completo.
Por exemplo, se você optar por testar o cérebro, então é melhor testar apenas o []-+<>
subconjunto, pois a entrada não é suportada e a saída é descartada (veja abaixo).
Quando se trata do programa "controller" (no qual você está jogando golfe), não há requisitos especiais. Aplicam-se restrições de idioma normal.
Como criar uma lista infinita de programas
A maioria das linguagens de programação pode ser representada como uma série de símbolos de um alfabeto finito. Nesse caso, é relativamente fácil enumerar uma lista de todos os programas possíveis em ordem crescente. O alfabeto que você usa deve ser representativo dos requisitos do idioma de destino. Na maioria dos casos, isso é ASCII imprimível. Se o seu idioma suportar Unicode como um recurso adicional, você não deve testar todas as combinações possíveis de caracteres Unicode, apenas ASCII. Se o seu idioma usar apenas []-+<>
, não teste as várias combinações de caracteres ASCII de "comentário". Idiomas como o APL teriam seus próprios alfabetos especiais.
Se o seu idioma é melhor descrito de alguma maneira não alfabética, como Fractran ou Turing Machines, existem outros métodos igualmente válidos para gerar uma lista de todos os possíveis programas válidos.
Interpretando uma lista crescente de programas
A parte principal desse desafio é escrever um intérprete paralelo para uma lista crescente de programas. Existem algumas etapas básicas para isso:
- Adicione um número finito de programas à lista
- Interprete cada programa da lista individualmente por um período finito de tempo. Isso pode ser realizado executando uma etapa de instrução para cada um. Salve todos os estados.
- Remova todos os programas de finalização / de lançamento de erros da lista
- Saída dos programas com interrupção limpa *
- Adicione mais alguns programas à lista
- Simule cada programa, alternando a execução de programas mais antigos de onde parou
- Remova todos os programas de finalização / de lançamento de erros da lista
- Saída dos programas com interrupção limpa *
- repetir
* Você só deve emitir programas que parem corretamente. Isso significa que não houve erros de sintaxe ou exceções não detectadas lançadas durante a execução. Os programas que solicitam entrada também devem ser finalizados sem a saída deles. Se um programa produz saída, você não deve encerrá-la, apenas jogue a saída fora.
Mais regras
- Você não deve gerar novos encadeamentos para conter os programas testados, pois isso descarrega o trabalho de paralelização no SO host / outro software.
- Editar: para fechar possíveis brechas futuras, você não tem permissão para
eval
(ou qualquer função relacionada) parte do código do programa testado . Você podeeval
bloquear um código a partir do código do intérprete. (A resposta BF-in-Python ainda é válida sob essas regras.) - Isso é código-golfe
- O idioma em que você enviou seu envio não precisa ser o mesmo que você está testando / produzindo.
- Você deve assumir que sua memória disponível é ilimitada.
- Ao provar a integridade de Turing, você pode assumir que a entrada está codificada no programa e a saída pode ser lida no estado interno do programa.
- Se o seu programa se exibir, provavelmente está errado ou é poliglota.
"If your program outputs itself, it is probably wrong or a polyglot."