El lenguaje de los while
programas puede expresar las funciones computablemente enumerables. (Esto es cierto incluso si las únicas operaciones aritméticas en variables son, por ejemplo, incremento y decremento).
Si while
se reemplaza por for
hacer bucles siempre delimitados, el lenguaje solo puede expresar las funciones recursivas primitivas.
Recientemente me di cuenta de la clase de funciones elementales , que están estrictamente por debajo de las funciones recursivas primitivas, pero todavía estrictamente por encima de la jerarquía exponencial.
Obviamente, sería posible definir un lenguaje de programación imperativo que capture exactamente las funciones elementales, por ejemplo, introduciendo operadores para la suma limitada y el producto. Sin embargo, mi pregunta es:
¿Existe un cambio sintáctico en el lenguaje de los
while
programas que lo restringe a las funciones elementales y que puede expresarse tan simplemente como la restricción (while
->for
) a las funciones recursivas primitivas?
Una restricción a for
programas en lugar también bastaría, por supuesto, y tal vez debería aclarar que no estoy buscando algo que está absolutamente como se ha dicho con sencillez, sólo algo con simplicidad comparables que no requiere la adición de operadores adicionales o similares .
Editar : Un ejemplo de for
lenguaje representativo es PL- {GOTO} de "Theory of Computation" (1974) de Brainerd y Landweber, en el que cada programa tiene un número finito pero sin restricciones de variables, cada una de las cuales puede contener un número natural, y que consiste esencialmente en los siguientes comandos:
X <- 0
(asignar 0 a una variable)X <- Y
(asigne el valor deY
aX
)X <- Y + 1
(asigne el sucesor del valor deY
aX
)LOOP X; ... END;
(repite el bloque deX
tiempos de código contenido ; no se modificaX
)
Los autores dan una prueba de que esto puede expresar exactamente las funciones recursivas primitivas. El lenguaje PL no coincide perfectamente con la pregunta, ya que utiliza en GOTO
lugar de while
, y PL- {GOTO} se deriva de PL al eliminarlo GOTO
. Sin embargo, los programas de PL son tan poderosos como while
los programas, y esta GOTO
transformación: extracción es tan simple como la sustitución declararon while
con for
. (Posiblemente quizás incluso un poco más simple).
Edición 2 : http://en.wikipedia.org/wiki/Total_Turing_machine sugiere que este resultado se remonta a: Meyer, AR, Ritchie, DM (1967), La complejidad de los programas de bucle , Proc. de las Reuniones Nacionales de la ACM, 465.
fuente
for
bucles, pero nunca he visto una prueba. ¿Tienes?LOOP
(lo que he llamadofor
) comoGOTO
Turing completo, pero que sinGOTO
él solo puede expresar las funciones pr. Editaré la pregunta para incluir una breve descripción de este idioma.Respuestas:
Según un resultado clásico de Meyer y Ritchie (mencionado en el documento citado en la pregunta), las funciones elementales se caracterizan por los programas LOOP en los que la profundidad de anidamiento de los bucles for se limita a un máximo de 2.
fuente
Mi suposición se basa únicamente en la definición: una respuesta podría ser "restricción de bucles a bucles embarazosamente paralelos
for
".Mi definición de trabajo de "
for
bucle embarazosamente paralelo " es una en la que ninguna iteración tiene ninguna dependencia de datos en ninguna otra iteración y hay una función reductora binaria para agregar la salida (junto con un caso base). Puntos de vergüenza adicionales si la función reductora es asociativa, pero no sé si esa distinción limitaría el poder del lenguaje.Si limitamos los reductores permitidos a la suma y la multiplicación, me parece probable que cualquier programa implementado bajo estas restricciones pueda escribirse como una función recursiva elemental (y viceversa). Estoy menos seguro acerca de reductores más generales.
Entonces, una forma divertida de decirlo es que la única construcción en bucle de su idioma es MapReduce.
No soy un experto en el área, pero me gustaría proponer esto como una hipótesis y ver cuáles son las opiniones de las personas.
Editar . Para probar o refutar este hecho, podríamos usar una caracterización útil de Meyer y Ritchie: un programa LOOP implementa una función elemental si se ejecuta en el tiempo donde representa una torre de algún tamaño fijo .O(22…n) … k
Esto parece claramente cierto para los
for
programas paralelos cuando la función reductora se limita a la suma o la multiplicación, pero parece ser falsa para una opción más amplia de reductor. Me gustaría encontrar que podemos obtener las funciones elementales siempre que restrinjamos el reductor para que se ejecute en tiempo polinómico (la multiplicación es lineal en este modelo), pero tendré que intentar resolverlo.Editar 2 . Bien, parece que deberíamos permitir exactamente las funciones reductoras que se ejecutan en tiempo polinómico para recuperar las funciones recursivas elementales. [1] Entonces nos damos cuenta de que esta restricción no es tan interesante, porque las funciones polinómicas en este modelo son solo aquellas expresadas por programas con un solo
for
bucle o unfor
bucle paralelo con una función reductora sin bucle. Así que básicamente hemos recuperado la restricción de que los programas tienen hasta dosfor
bucles anidados , pero acabamos de mover esa restricción a la función reductora.Resumen: La caracterización parece ser cierta para los reductores que se ejecutan en tiempo polinómico. No está claro si esto es interesante.
[1]: en la entrada , deje que la función reductora se ejecute en el tiempo durante algunos . Podemos argumentar por inducción que un programa que contiene bucles paralelos anidados se ejecuta en el tiempo para una pila de exponentes de tamaño constante.n O(nk) k 22…n
for
En unn n f(n) f(n)∈O(22…n)
for
bucle embarazosamente paralelo en la entrada , podemos ejecutar hasta iteraciones, cada una de las cuales (dado que son independientes) se ejecuta en el tiempo hasta . Suponga que para la inducción para una pila exponencial de profundidad constante.Si la función reductora es , el bucle consta de composiciones de en una entrada de tamaño : . Suponiendo que el tiempo de ejecución en el tamaño de entrada está limitado por para cada paso del reductor, por lo que se ejecuta en el tiempo , que está dominado asintóticamente por . Por suposición inductiva, estaba delimitada por para una pila de exponentes de tamaño constante, por lo que lo mismo debe ser cierto para nuestro tiempo de ejecución.n p f ( n ) p ( f ( n ) , p ( f ( n ) , ... ) ) x x k O ( f ( n ) k n ) f ( n ) 2 2 n f ( n ) 2 ... np n p f(n) p(f(n),p(f(n),…)) x xk O(f(n)kn) f(n)22n f(n) 2…n
for
Y, por otro lado, por supuesto, si el reductor funciona en tiempo exponencial, entonces este argumento fallará y obtendremos una pila exponencial cuyo tamaño depende de , lo que significa que podemos implementar una función recursiva no elemental.n
fuente