Sé que, en los lenguajes de programación imperativos, un bucle while-do es suficiente como una construcción de flujo de control para completar el lenguaje Turing (en lo que respecta al flujo de control, por supuesto, también necesitamos memoria ilimitada y ciertos operadores ...) . La esencia de mi pregunta es: ¿un ciclo do-while tiene el mismo poder computacional que un ciclo while-do? En otras palabras, ¿puede un idioma ser Turing completo si es imposible omitir las instrucciones por completo?
Me doy cuenta de que algunas de las semánticas aquí podrían ser un poco ambiguas, así que permítanme formular la pregunta real con un ejemplo específico:
Brainfuck (BF) es un tarpit de Turing donde el único flujo de control es un ciclo while-do, denotado como [...]
(hay una especificación de lenguaje completa en la parte inferior de la pregunta, en caso de que no esté familiarizado con Brainfuck). Definamos un nuevo lenguaje BF *, donde ,.+-<>
tenga la misma semántica que en BF, pero en lugar de la []
que tenemos, {}
denota un ciclo do-while. Es decir, la única diferencia con BF es que cada bucle se ejecuta al menos una vez antes de que se puedan omitir más iteraciones.
¿Está BF * Turing completo? Si es así, me interesaría cómo podría traducir BF a BF *. Si no es así, ¿cómo pruebo eso?
Algunas observaciones mías:
- No todos los programas BF se pueden traducir a BF *. Por ejemplo, es imposible escribir un programa en BF * que pueda o no leer o imprimir un valor; si el programa potencialmente imprime uno o más valores, siempre imprimirá al menos uno. Sin embargo, puede haber un subconjunto de BF completo de Turing que se puede traducir a BF *.
- No podemos simplemente traducir
[f]
(dondef
hay algún programa arbitrario, Brainfuck que consiste solo en+-[]<>
) a (en un intento de cancelar el efecto de la primera iteración), porque a) no todas las funciones computables tienen un inverso computable yb) incluso si lo hiciera, no necesariamente tendría menos bucles que, por lo tanto, aplicar este paso de forma recursiva no garantiza que termine en primer lugar.f-1{f}
f-1
f
Aquí hay una descripción rápida sobre el lenguaje Brainfuck. Brainfuck opera en una cinta infinita donde cada celda contiene valores de bytes, inicialmente cero. Los desbordamientos se envuelven, por lo que al incrementar 255 se obtiene 0 y viceversa. El lenguaje consta de 8 instrucciones:
+ Increment the current cell.
- Decrement the current cell.
> Move tape head to the right.
< Move tape head to the left.
, Input a character from STDIN into the current cell.
. Output the current cell as a character to STDOUT.
[ If the current cell is zero, jump past the matching ].
] If the current cell is non-zero, jump back to just behind the matching [.
[]
no está definiendo exactamente un bucle "while do" en BF. Como en su tabla, los corchetes izquierdo y derecho evalúan la celda actual cero / no cero. Entonces, ¿cuál es la descripción exacta de la {}
lógica de evaluación de llaves correspondiente ? Sugerir más diálogo / discusión en Computer Science Chat . también sus "observaciones" son más como "postulados" o "proposiciones" sin prueba.
{}
sería {
no hacer nada en absoluto y }
lo mismo ]
. No tendré mucho tiempo en los próximos días, pero me reuniré con usted en el chat cuando encuentre algo de tiempo.
{}
y quitando []
, es BF * Turing completo. con el entendimiento de que BF []
es una construcción solo algo similar / análogo a un ciclo while-do en los lenguajes completos de Turing.