El objetivo de este desafío es (eventualmente) generar todos los posibles programas de detención en el idioma que elija. Al principio esto puede sonar imposible, pero puede lograr esto con una elección muy cuidadosa de la orden de ejecución.
A continuación se muestra un diagrama ASCII para ilustrar esto. Deje que las columnas representen una numeración de cada programa posible (cada programa es un número finito de símbolos de un alfabeto finito). Deje que cada fila represente un paso singular en la ejecución de ese programa. An X
representa la ejecución realizada por ese programa en ese paso de tiempo.
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 puede ver, los programas 2 y 4 no se detienen. Si los ejecutara uno a la vez, su controlador se quedaría atascado en el bucle infinito que es el programa 2 y nunca generaría los programas 3 y posteriores.
En su lugar, utiliza un enfoque de cola de milano . Las letras representan un posible orden de ejecución para los primeros 26 pasos. Los *
s son lugares donde ese programa se ha detenido y se emite. Los .
s son pasos que aún no se han ejecutado.
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 el idioma de destino
El idioma de destino (el que se interpreta en paralelo) debe ser Turing completo. Aparte de eso, puede ser cualquier idioma que sea Turing completo, incluidos los subconjuntos Turing completos de idiomas mucho más grandes. También es libre de interpretar cosas como las reglas del sistema de etiquetas cíclicas. También puede crear un idioma para probar, siempre y cuando pueda mostrar por qué es Turing completo.
Como ejemplo, si elige probar brainfuck, lo mejor es probar solo el []-+<>
subconjunto, ya que la entrada no es compatible y la salida simplemente se descarta (ver más abajo).
Cuando se trata del programa "controlador" (que está jugando al golf), no hay requisitos especiales. Se aplican restricciones de idioma normales.
Cómo crear una lista infinita de programas
La mayoría de los lenguajes de programación se pueden representar como una serie de símbolos de un alfabeto finito. En este caso, es relativamente fácil enumerar una lista de todos los programas posibles en orden creciente. El alfabeto que use debe ser representativo de los requisitos del idioma de destino. En la mayoría de los casos, esto es ASCII imprimible. Si su idioma admite Unicode como una característica adicional, no debe probar todas las combinaciones posibles de caracteres Unicode, solo ASCII. Si su idioma solo usa []-+<>
, no pruebe las diversas combinaciones de caracteres ASCII de "comentario". Idiomas como APL tendrían sus propios alfabetos especiales.
Si su idioma se describe mejor de alguna manera no alfabética, como Fractran o Turing Machines, existen otros métodos igualmente válidos para generar una lista de todos los posibles programas válidos.
Interpretar una lista cada vez mayor de programas
La parte clave de este desafío es escribir un intérprete paralelo para una lista creciente de programas. Hay algunos pasos básicos para esto:
- Agregue un número finito de programas a la lista
- Interprete cada programa en la lista individualmente por un período de tiempo finito. Esto se puede lograr realizando un paso de instrucción para cada uno. Salva a todos los estados.
- Eliminar todos los programas de terminación / lanzamiento de errores de la lista
- Salida de los programas limpiamente detenidos *
- Agregue algunos programas más a la lista
- Simule cada programa a su vez, retomando la ejecución de programas antiguos donde se dejó
- Eliminar todos los programas de terminación / lanzamiento de errores de la lista
- Salida de los programas limpiamente detenidos *
- repetir
* Solo debe generar programas que se detengan limpiamente. Esto significa que no hubo errores de sintaxis o excepciones no detectadas lanzadas durante la ejecución. Los programas que solicitan información también deben finalizar sin generarlos. Si un programa produce resultados, no debe terminarlos, solo bótelos.
Más reglas
- No debe generar nuevos subprocesos para contener los programas probados, ya que esto descarga el trabajo de paralelización en el sistema operativo host / otro software.
- Editar: para cerrar posibles lagunas futuras, no se le permite
eval
(ni ninguna función relacionada) una parte del código del programa probado . Usted puedeeval
un bloque de código a partir del código del intérprete. (La respuesta BF-in-Python sigue siendo válida según estas reglas). - Esto es código golf
- El idioma en el que escribe su envío no necesita ser el mismo que el idioma que está probando / enviando.
- Debe suponer que su memoria disponible no tiene límites.
- Al probar la integridad de Turing, puede suponer que la entrada está codificada en el programa y que la salida se puede leer en el estado interno del programa.
- Si su programa se genera solo, probablemente sea incorrecto o políglota.
"If your program outputs itself, it is probably wrong or a polyglot."