Autor Tema: Desafío: programa que ejecute su propio código como input

0 Usuarios y 1 Visitante están viendo este tema.

12 Enero, 2012, 11:57 am
Leído 5367 veces

Elius

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 399
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
En teoría de la computabilidad se plantea muchas veces el caso teórico de programas que ejecutan su propio código como input.
Sin embargo, nadie ha podido construir uno solo, de modo que, si alguien puede hacerlo, podríamos tener un ejemplo de ese ente teórico.

Saludos!

12 Enero, 2012, 05:54 pm
Respuesta #1

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
Hay infinitos programas que ejecutan su propio código como input.

Basta incluir en el programa una rutina que lea archivos de texto.

______________

En C:

Programa almacenado en el archivo

imposible.c


#include stdio.h
#include stdarg.h


int main(int argc, char *argv[]) {
 
   FILE *f;
   char c;

   if (argc < 1) {
     printf("El programa no ha recibido INPUTS/n/n");
     return 1;
   }
 
   f = fopen(argv[1],"r");
 
   if (f == NULL) {
     printf("Error al intentar abrir el archivo.");
     return 1;
   }

   while (feof(archivo) == 0)   {
       fgets(c,1,f);
       printf("%c",c);
   }
         
   printf("/n/n/n");
   printf("X");                    /* 1 */

   return 0;
}


______________________

Como se ve, el programa anterior lee los caracteres de un archivo que se le pasa como parámetro y los muestra en la pantalla.

El mismo programa se puede pasar a sí mismo como INPUT, con la siguiente llamada:

imposible imposible.c

_____________________

Para conseguir infinitos programas del tipo anterior, hay que reemplazar la línea que dice

printf("X");                    /* 1 */

por muchas líneas así:

printf("X");                    /* 1 */
printf("X");                    /* 2 */
printf("X");                    /* 3 */
printf("X");                    /* 4 */

... ...

printf("X");                    /* n */

_____________

con n = 1, 2, 3, 4, ...

(Incluso se puede hacer un programa que genere estos programas).

____________

O sea que, infinitos, haylos..., porque finitos no son.

12 Enero, 2012, 07:06 pm
Respuesta #2

Elius

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 399
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
@argentinator
Programas que EJECUTEN su propio código como input. Pueden ser programas intérpretes, como lo son PERL, awk, bash, etc. O bien tienen que  leer el binario ejecutable, no el texto fuente, y pasarle el control.

Si consideran que tienen uno, ejecútenlo con traza, y la manden junto con el fuente, por favor.

En tu caso, no es válido que leas "imposible.c", sino

$consola-> dbx -trace imposible imposible > traza_imposible.txt 2>&1

"dbx" es el debugger de C en Unix, "-trace" para que haga la traza, y "2>&1" para que los mensajes de error vayan al archivo de traza. Varía según el sistema operativo, lo que te mando es SunOs o AIX de IBM, pero en Unix y en Linux debería haber cosas parecidas.

Saludos!





12 Enero, 2012, 07:19 pm
Respuesta #3

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
Si compilás el programa anterior, te queda un ejecutable, y es lo mismo.

En la llamada, en vez de hacer

imposible imposible.c

se hace

imposible.exe imposible.exe

______

Si no, si querés un programa que se ejecute a sí mismo, que "ya sea ejecutable", puede ser éste:

________________

(En Windows, en línea de comandos)

El programa se llama "imposible.bat", y tiene una sola línea que dice así:

@TYPE %1

Se puede llamar ese programa pasando a él mismo como parámetro:

imposible.bat imposible.bat

El resultado vuelca el texto del programa.

_____________

Si querés el ejecutable no veo cuál sea el problema, es lo mismo, siempre y cuando el programa acepte un parámetro.


Con cualquier compilador estándar de C podés hacer el ejecutable y lograr lo que te digo.
Si se complica imprimir los caracteres del ejecutable en pantalla, se puede hacer otro tipo de programa, que simplemente "cuente" los caracteres del INPUT.


12 Enero, 2012, 07:23 pm
Respuesta #4

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
En tu caso, no es válido que leas "imposible.c", sino

$consola-> dbx -trace imposible imposible > traza_imposible.txt 2>&1


Entonces poné algo que diga

$consola-> dbx -trace imposible.exe imposible.exe > traza_imposible.txt 2>&1

_________
(La extensión EXE es en Windows, no sé en tu sistema qué extensión tienen los ejecutables).


No sé qué es lo que querés inventar.

Hacer que un programa acepte otros programas como parámetro es fácil.
Después pasarle a un programa a sí mismo como parámetro también, es sólo decidirse a escribir una pequeña línea de comandos y apretar enter.

12 Enero, 2012, 07:56 pm
Respuesta #5

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 12,032
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Hola, Elius. Vaya por delante que me encantaría que lograras algo como lo que te propones, te lo digo de verdad, -me encantan los milagros  :) - pero, suponiendo que lo consiguieras, nunca podrías haciendo usando estos lenguajes de alto nivel; esos comandos "simples" son en realidad subrrutinas, es como si dieras a un interruptor, no ves que por dentro se juntan dos cables y, por tanto, no tienes información suficiente para evaluar o analizar.
 Cuando defines una simple variable, por ejemplo, en Jabascript, en PHP o en lo que quieras, ocurren varias operaciones; por ejemplo:

$A=1; $A=1

 Y el ordenador hasta ahí no hace nada, y tú te crees que por dentro está tan tranquilo; pues no, tiene un conflicto, se le está pidiendo algo imposible para él, pues para cargar 1 en A hay que darle primero la orden de que descargue; no puede cargar un registro si ya está cargado, tiene que haber una instrucción POP antes de la instrucción PUSH. Si tú, programando en código máquina, (fundamental que veas este enlace u otros mejores o más explicativos del funcionamiento que pudiera haber http://es.wikipedia.org/wiki/Lenguaje_de_m%C3%A1quina) y haces eso mismo -traducido a código máquina- al ordenador se le pone la pantalla en blanco y lo tienes que apagar porque no responde nada; te lo digo por experiencia propia, porque me pasó cuando intenté aprender un poco de eso.
 Por tanto, para seguir trabajando sobre esto, que me parece muy bien que lo hagas y que se intenten cosas imposibles, vuelvo a repetir -son las que más nos enseñan en la vida- creo que necesitarías utilizar el código que usa la máquina.

Un saludo cordial.   

12 Enero, 2012, 07:57 pm
Respuesta #6

Elius

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 399
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
@argentinator
No invento nada, sólo pregunto si alguien puede hacerlo.

El fuente de "imposible" no me sirve, porque lee texto, no binario. Así que no puedo programar imposible.exe porque no sé cuál es el fuente.

Probablemente no se entiende bien. Pero no sé cómo decirlo mejor: no conozco ningún programa que EJECUTE su propio código y termine bien o entre en loop. Eso es todo. Por supuesto, tiene que ver con el Halting Problem.

No sé qué es lo que querés inventar.

Hacer que un programa acepte otros programas como parámetro es fácil.
Después pasarle a un programa a sí mismo como parámetro también, es sólo decidirse a escribir una pequeña línea de comandos y apretar enter.

No te irrites, ya digo que estoy haciendo planteos muy radicales. Pero si lo ves fácil, es cuestión de intentarlo.

Saludos!


Saludos!




12 Enero, 2012, 08:00 pm
Respuesta #7

Elius

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 399
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
@feriva
No estoy tratando de lograrlo, al contrario, mi opinión es que no existen programas así. Pero en teoría de la computabilidad aparecen como hongos luego de la lluvia. Se supone que existen. Yo creo que no. Esa es la cuestión.

Creo entender que tú piensas lo mismo, tal vez me expliqué mal, pero el tema es muy elusivo, y cuesta expresarse con la precisión y claridad necesarias.

Saludos

12 Enero, 2012, 09:44 pm
Respuesta #8

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
Pero si lo ves fácil, es cuestión de intentarlo.


No se trata de "intentarlo",
sino que ya te lo dí hecho.
¿Qué más tengo que hacer?
No te dí el ejecutable, pero es lo mismo.

El programa imposible.c es el fuente.
Con un compilador estándar, como gcc,
se genera el ejecutable imposible.exe.

Una vez generado, se lo puede ejecutar en tu sistema (si no es linux, quizá el ejecutable se llame imposible.out).

Es un programa ejecutable que acepta como parámetro otros archivos.

Se puede ejecutar:

imposible.exe hola.txt
imposible.exe otroarch.dll
imposible.exe denuevo.png


Y finalmente, le puedo pasar como parámetro a sí mismo:

imposible.exe imposible.exe

_____________

No voy a cargar el ejecutable acá, porque el foro no admite archivos adjuntos ejecutables,
y porque volcar el contenido conllevaría que aparezcan caracteres unicode no-imprimibles.

Pero "no-imprimible" no quiere decir "no-procesable".

El archivo se puede leer y "hacer algo" con él, por ejemplo, contar su número de caracteres, o imprimir una "@" por cada byte del archivo, como en el siguiente código:


#include stdio.h
#include stdarg.h

int main(int argc, char *argv[]) {
 
   FILE *f;
   char c;

   if (argc < 1) return 1; /* Error 1: no hay INPUTs */
 
   f = fopen(argv[1],"r");
 
   if (f == NULL)  return 2; /* Error 2: apertura de archivo errónea */

   while (feof(archivo) == 0)   {
       fgetc(f);
       printf("@");
   }

   fclose(f);
         
   return 0;
}


____________

Cualquier programa que admita un archivo como parámetro satisface lo que vos planteás.
Si después el programa hace algo o no con lo que le pasaste como parámetro, es cosa de él.

Pero pasar un programa como parámetro a otro es algo trivial.
Y pasarse a sí mismo como parámetro también es trivial, porque es cuestión de hacer una llamada del programa, con él mismo como parámetro.

¿Cómo no me voy a enojar, si es algo tan obvio para cualquiera que haya programado dos líneas en su vida?

Y ni siquiera hace falta ser programador para esto, sino usar algún shell que permita llamar programas con parámetros.

Agarrás cualquier programa (como el RAR.EXE por ejemplo) y le pasás cualquier cosa como parámetro  (por ejemplo, el mismo RAR.EXE).
Te va a saltar un mensaje de error, porque RAR.EXE no es un archivo de tipo "comprimido", pero el archivo está procesado igual.


12 Enero, 2012, 10:09 pm
Respuesta #9

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 12,032
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
@feriva
No estoy tratando de lograrlo, al contrario, mi opinión es que no existen programas así. Pero en teoría de la computabilidad aparecen como hongos luego de la lluvia. Se supone que existen. Yo creo que no. Esa es la cuestión.

Creo entender que tú piensas lo mismo, tal vez me expliqué mal, pero el tema es muy elusivo, y cuesta expresarse con la precisión y claridad necesarias.

Saludos

Quizá no te entienda lo que quieres decir, eso sí puede ser, Elius. Por otro lado, aunque haya programado algo, estoy muy lejos de ser un conocedor de la teoría de la computabilidad.
Ahora, eso que dices, de que los programas se ejecutan a sí mismos como hongos, se puede experimentar de la siguiente manera: haz un programa en el lenguaje que quieras y que este programa sea el que quieras; pero con la condición de que a las variables que uses las bautices exactamente con el mismo nombre de las variables del sistema de Windows (o Linus o el que uses). Tienes que asegurarte de que las variables entren en funcionamiento mientras corres el programa (mejor en un disco duro en el que no guardes nada importante  :laugh: ).
En este caso pueden pasar varias cosas: que el ordenador te avise y no ejecute, que lo ejecute y que aparentemente no pase nada pero, más tarde, te des cuenta de que ha cambiado el color de un icono, de que el rabillo de la "ñ" no sale, etc. (con lo que Windows ya no es exactamente el mismo sistema operativo que era) o bien pude que el Windows se trague alguna variable verdaderamente importante para el funcionamiento y tengas que formatear el disco.

 Eso sería que un programa se interpretara a sí mismo, que el sistema operativo ejecutara el propio sistema operativo; y basta nombrar a una variable importante con el nombre de una variable del sistema -en un programa distinto, no ya en un programa gemelo del Windows) para que la líe.

 Un saludo.