Hola,
Pero si nos permitimos redefiniciones de las condiciones iniciales del programa que representa a la MT de Turing, yo podría agregar lo siguiente, para evitar que Turing use el código de la máquina testeadora como input:
@if '%0'=='%1' ( echo Turing: esto no es válido Compara el input con su propio nombre
goto :fin )
@if '%2'=='' universal.bat %1 %1
%1 %2
:fin
Output:
C:\> UNIVERSAL UNIVERSAL UNIVERSAL
Turing: esto no es v?lido
C:\>
Tienes razón, pero por un lado eso no invalida para nada la demostración de Turing (porque ahora todo programa con dos inputs iguales para), y por otro lado ese problema se puede solventar de varias maneras (por ejemplo considerando el mismo programa que te propuse, pero haciendo que ignore el input que le metas y se dedique a copiarse y ejecutarse a sí mismo).
Lo que me parece incomprensible es que para no sacar el simple y humilde mensajito "Falta un argumento", se hace entrar al proceso no ya en un bucle infinito, que sólo consume tiempo, sino a una cadena potencialmente infinita de llamadas que pueden hacer colapsar la memoria de la máquina. Los sistemas operativos tienen defensas para casi todo, pero no para la proliferación de procesos.
En resumen, no llega a terminar normalmente, en el caso "ingenuo" (sin sentencias "ad hoc"), porque se queda sin input; y en el caso "malicioso" (porque sabe que se queda sin input pero trata de ocultarlo), porque se queda leyendo infinitamente su input, o su input es infinito, como prefieras.
En ningún caso le serviría a Turing, me parece.
Hombre, no creo que "incomprensible" sea la palabra adecuada. Este programa es estúpido, pero creo que es, salvo pequeñas variantes, la única posibilidad de que un programa haga lo que pidas (que se ejecute a sí mismo, en un sentido bastante fuerte), y obviamente está pensado únicamente como ejemplo de lo que pedías. El input del programa es finito: es el propio programa. El programa hace exactamente lo que debe hacer, tomar un único input (él mismo) y ejecutar su programación. Que en el proceso haga infinitas llamadas a sí mismo es irrelevante. Es un hecho que el programa funciona (el ordenador lo ejecuta vaya) y nunca para, que era lo que pedías inicialmente. Obviamente, si empiezas a poner condiciones cada vez más restrictivas no habrá ningún programa que las satisfaga.
De todas maneras, echa un vistazo a la siguiente variación:
Considera una máquina universal U(m,n). Ahora sea U'(n) la máquina que hace lo siguiente: modifica n añadiendo al final del código del programa una sentencia estúpida, por ejemplo que imprima algo en pantalla. Digamos que este nuevo código es n'. A continuación el programa computa U(n,n'). Sea N una modificación estúpida del código de U' y considera U'(N). Primero se modifica el programa N de forma estúpida con código N' y se ejecuta U(N, N'). Pero U(N,N') computa exactamente lo mismo que U'(N') (más una salida en pantalla). Y esto te hace un código N'' que hace lo mismo que N y que N' (salvo impresiones en pantalla), y te computa U(N',N''), etcétera. El resultado es el mismo que antes, y ahora no hay autoaplicación por ningún sitio (los programas son todos distintos, aunque tengan una parte en común). Así que si ves un problema en esto, el problema no viene de la autoaplicación de programas (por lo menos en sentido estricto).
Sobre la última afirmación, no veo por qué no le serviría a Turing (más bien no entiendo en qué sentido lo dices).
El caso Ivorra también es "ad hoc": en vez de poner dentro del código una previsión ante la falta de input, pone como hipótesis que ante la cinta en blanco entra en loop o termina "bien". En ese caso siempre hay una respuesta ya predeterminada, y no se puede llegar a la contradicción que necesita Turing. Supongamos que ante la falta de input la máquina interna loopea. La máquina externa para, y siempre es así, no podemos agregar: "y si la máquina interna para, la máquina externa loopea", porque ese caso no se da nunca. Ergo, no hay contradicción.
Es que para empezar a Turing le dan igual los inputs, en sus máquinas los inputs son únicamente una convención "psicológica", nada más. Una máquina con la cinta en blanco hará lo que le mande su programación. Sobre lo que dices de que la demostración de Turing no vale, no sé si lo entiendo bien (¿quién es la máquina interna y la externa? ¿la externa es la que decide si una máquina dada para o no y la interna sobre la que se ha de decidir si para?) De todos modos, en la demostración de Turing lo único que hace falta es suponer que la máquina que decide si otra con un input dado para o no, siempre para (y funciona bien), lo que haga si no le das un input a la máquina interna es irrelevante, porque siempre tiene input en la demostración.
En el caso que planteé yo, de autoaplicación pura sin predicción, en el caso de las MT es una MUT que llama a otra MUT que no tiene máquina objeto que ejecutar.
Considera que no es simplemente que faltan datos en la cinta, en el caso de la MUT si la cinta está en blanco FALTA UNA MÁQUINA COMPLETA.
Sí, se puede decir, "bueno, si no tengo input para pasarle considero que es una máquina con la cinta en blanco", pero en ese caso no le queda otra alternativa que loopear, no puede parar porque NO TIENE MANERA DE "SABER" que TODA la cinta está en blanco. Tiene que seguir leyendo eternamente por si viene algún 0 o un 1. Entonces la máquina extena se queda eternamente esperando a su máquina interna; es decir, no termina nunca de procesar CARGAR su input.
Esto que dices es falso porque creo que no estás teniendo en cuenta una cosa: en las máquinas de Turing la computación es local. Es decir, lo que haga una máquina en el paso siguiente depende exclusivamente de la casilla que este leyendo el cabezal y del estado interno de la máquina. Una máquina de Turing no lee primero toda la cinta y luego hace cosas (obviamente eso es imposible porque la cinta es infinita). Puede ser que esté programada para que en el estado inicial leyendo una casilla en blanco pase directamente al estado final (y entonces lo hará siempre cuando le des una cinta en blanco, pero también lo hará si le das una cinta con un millón de unos y la inicias leyendo una casilla en blanco). O puede ser que esté programada para que en el estado inicial empezando con una casilla en blanco pase a un estado \( q_1 \), y que la máquina en estado \( q_1 \) leyendo una casilla en blanco avance una casilla a la derecha y vuelva al estado \( q_1 \), y que en este estado \( q_1 \) cuando esté leyendo un 1 pase al estado final. Entonces si le empiezas con una cinta en blanco la máquina loopeará, pero igual lo hará si le das una cinta con un millón de 1's y la inicias en una casilla que esté a la derecha de todos ellos.
En las máquinas reales uno podría decir también: se queda esperando eternamente su input, es decir, se detiene. Pero eso es detectable, hay tercer estado que es no terminó de procesar ni loopeó. No tuvo input por timeout. En las MT una combinación de unos y ceros puede indicar "nulo", y mandarla a un estado que no es terminal. Es cuestión de definición, la suposición de Ivorra no es forzosa.
Insisto: las máquinas de Turing no tienen input tal como tú lo estás considerando, no es más que una convención de decir que el input de la función que computa es tal si se inicia la máquina con una cinta en tal configuración. Pero al margen de convenciones, la máquina de Turing no distingue en ningún caso si la cinta está inicialmente en una configuración o en otra, ella mira qué es lo que hay en la casilla en la que está (y únicamente en esa) y hace lo que le dice su programación. Si quieres pensarlo así, en una máquina de Turing el "input" (ahora entendido como los datos que toma en cuenta la máquina para decidir lo que va a hacer en el siguiente paso) en cada paso es únicamente la casilla en la que está y el estado interno de la máquina. Para una máquina de Turing no tiene ningún sentido "cargar" el input.
Saludos