La inspiración para esta pregunta es la siguiente (vaga) pregunta: ¿Cuáles son los fundamentos lógicos / del lenguaje de programación para tener una IA que pueda razonar sobre su propio código fuente y modificarlo?
Esto no es del todo riguroso, así que aquí está mi intento de extraer una pregunta concreta. Hay dos cosas que me interesan:
(A) Un lenguaje de programación P que puede representar y manipular sus propios programas como un programa de tipo de datos (por ejemplo, como un AST). (Si lo desea, un objeto de tipo Programa se puede convertir en una Cadena, que es el texto de un programa válido en ese idioma. Esto sería lo contrario de lo que hace un compilador).
(B) Un método para razonar sobre lo que hace un programa en lenguaje P. Aquí hay dos niveles en los que estoy pensando:
- Otro lenguaje Q (con capacidades de prueba de teoremas) que modela lo que hace un programa P. Debe poder expresar y probar declaraciones como "el resultado de ejecutar el Programa p es falso".
- Una forma de razonar sobre lo que hace un programa p: El programa lo hace en el lenguaje P mismo. (Entonces estamos tomando P = Q arriba).
¿En qué medida se ha implementado algo como esto, o cuál es el progreso en esta dirección? ¿Cuáles son los obstáculos prácticos? A la luz de la intención original de la pregunta, ¿cuál es la mejor manera de formalizar el problema?
* *
Como muestran las respuestas (¡gracias!), Tanto (A) como (B1) se pueden hacer por separado, aunque parece que hacerlas juntas es más una pregunta de investigación.
Estos fueron algunos de mis primeros pensamientos sobre la pregunta (advertencia: bastante vago). Véanse también mis comentarios sobre la respuesta de Martin Berger.
Estoy interesado en el lenguaje de programación que modela el mismo lenguaje de programación, en lugar de uno más simple (entonces P = Q arriba). Esto sería una "prueba de concepto" de un programa capaz de "razonar sobre su propio código fuente". Los lenguajes de programación de tipo dependiente pueden dar garantías sobre los resultados de sus funciones, pero esto no cuenta como "razonamiento sobre su propio código fuente" más que como un "¡Hola mundo!" cuenta como una quine en un lenguaje que imprimirá automáticamente una cadena desnuda --- debe haber algún tipo de cita / autorreferencia. El análogo aquí es tener un tipo de datos que representa el Programa.
Parece un proyecto bastante grande: cuanto más simple es el lenguaje, más difícil es expresar todo dentro de él; cuanto más complicado es el idioma, más trabajo hay que hacer para modelar el idioma.
En el espíritu del Teorema de la recursividad, un programa puede "obtener" su propio código fuente y modificarlo (es decir, generar una versión modificada de sí mismo). (B2) luego nos dice que el programa debería poder expresar una garantía sobre el programa modificado (esto debería poder repetirse, es decir, debería poder expresar algo sobre todas las modificaciones futuras-?).
Respuestas:
Creo que estás preguntando sobre dos cosas diferentes.
Para fines analíticos, es útil mantenerlos separados. Me centraré en lo primero.
La capacidad de un lenguaje de programación para representar, manipular (y ejecutar) sus programas como los datos se conoce con términos tales como meta-programación o homoiconicidad .
De una manera (incómoda), todos los lenguajes de programación conocidos pueden hacer metaprogramación, es decir, utilizando el tipo de datos de cadena junto con la capacidad de invocar programas externos (compilador, enlazador, etc.) en cadenas (por ejemplo, escribiéndolos en el archivo sistema primero). Sin embargo, eso probablemente no sea lo que quieres decir. Probablemente tenga una buena sintaxis en mente. Las cadenas no son una buena sintaxis para la representación de programas porque casi todas las cadenas no representan programas, es decir, el tipo de datos de cadena contiene mucha 'basura' cuando se ve como un mecanismo de representación de programas. Para empeorar las cosas, el álgebra de las operaciones de cadena no tiene esencialmente conexión con el álgebra de la construcción de programas.
Lo que probablemente tengas en mente es algo mucho más agradable. Por ejemplo, si es un programa, entonces es , pero como datos disponibles para la manipulación y el análisis. Esto a menudo se llama cita . En la práctica, la cita es inflexible, por lo que usamos cuasi cita en su lugar, que es una generalización de la cita donde la cita puede tener 'agujeros' en los que se pueden ejecutar programas que proporcionan datos para 'llenar' los agujeros. Por ejemplo es una cuasicita que representa un condicional donde en lugar de una condición tenemos un agujeroPAG P⟨ P⟩ PAG [ ⋅ ] M ⟨ x > 0 ⟩ ⟨ i f
(Tenga en cuenta que es un programa normal (no un programa como datos) que devuelve un programa citado, es decir, un programa como datos). Para que esto funcione, necesita un tipo de datos para representar los programas. Típicamente, ese tipo de datos se llama AST (árbol de sintaxis abstracta), y puede ver (cuasi) comillas como mecanismos de abreviatura para AST.METRO
Varios lenguajes de programación ofrecen cuasicitas y otras características para la metaprogramación. Fue Lisp con su funcionalidad de macro que fue pionera en esta capacidad de tratar los programas como datos. Quizás desafortunadamente, el poder de las macros basadas en Lisp fue visto durante mucho tiempo para descansar en gran medida en la sintaxis minimalista de Lisp; No fue hasta MetaML (1) que se demostró que un lenguaje moderno y sintácticamente rico era capaz de metaprogramar. Desde entonces, MetaOCaml (2) (un descendiente de MetaML, importante por su avance en la búsqueda aún en curso para resolver el problema de cómo escribir programas como datos), Template Haskell (3) y Converge (4) (el primer idioma para obtener todas las características clave de metaprogramación en mi opinión) han demostrado que una variedad de lenguajes de programación modernos pueden albergar metaprogramación. Es importante darse cuenta de que podemos tomarcualquier lenguaje de programación y convertirlo en un lenguaje de que sea junto con la capacidad de representar (y evaluar) sus propios programas como datos.L m p LL Lm p L
La representación del resultado de la ejecución del programa, dada como datos, se logra agregando una función que toma un programa (dado como datos) como entrada y lo ejecuta , devolviendo su resultado. Por ejemplo, si es un programa que evalúa 17 y , la versión (cuasi-) citada de , es decir, como datos, entonces también devuelve 17. Hay toda clase de sutilezas aquí que estoy ignorando aquí, como la pregunta cuandoP ⟨ P ⟩ P P e v a l ( ⟨ P ⟩ ) P ⟨ P ⟩e v a l (⋅) PAG ⟨ P⟩ PAG PAG e v a l (⟨P⟩ ) se están evaluando programas metaprogramados (dando lugar a la distinción entre metaprogramado en tiempo de compilación y en tiempo de ejecución), qué hacer con los tipos o evaluaciones fallidas, qué sucede con las variables enlazadas y libres en el proceso de pasar de a o viceversa.PAG ⟨P⟩
En cuanto a la segunda dimensión, razonamiento sobre programas dados como datos. Tan pronto como pueda convertir los programas en datos, son datos "normales" y pueden razonarse como datos. Puede utilizar todo tipo de tecnología de prueba, por ejemplo, tipos dependientes o contratos o demostradores de teoremas interactivos o herramientas automatizadas, como Joshua ha señalado. Sin embargo, tendrá que representar la semántica de su idioma en el proceso de razonamiento. Si ese lenguaje, como lo requiere, tiene habilidades de metaprogramación, las cosas pueden volverse un poco complicadas y no se ha hecho mucho trabajo en esta dirección, siendo (5) la única lógica de programa para este propósito. También hay un trabajo basado en Curry-Howard sobre el razonamiento sobre metaprogramación (6, 7, 8). Tenga en cuenta que estos enfoques basados en la lógica, y el enfoque basado en el tipo (2) puede expresar propiedades que son válidas para todas las etapas futuras de metaprogramación. Aparte de (2) ninguno de esos documentos ha sido implementado.
En resumen: lo que solicitó se ha implementado, pero es bastante sutil y todavía hay preguntas abiertas, en particular sobre los tipos y el razonamiento simplificado.
W. Taha. Programación de etapas múltiples: su teoría y aplicaciones .
W. Taha y MF Nielsen. Clasificadores de entorno .
T. Sheard y S. Peyton Jones. Meta-programación de plantillas para Haskell .
L. Tratt. Meta-programación en tiempo de compilación en un lenguaje OO de tipo dinámico .
M. Berger, L. Tratt, Lógicas de programa para metaprogramación homogénea .
R. Davies, F. Pfenning, Un análisis modal de la computación por etapas .
R. Davies, Un enfoque de lógica temporal para el análisis del tiempo de enlace .
T. Tsukada, A. Igarashi. Una base lógica para los clasificadores de entorno .
fuente
No, no hay un sistema actual que realice los cuatro pasos en su sistema. Si desea diseñar un sistema, uno de los primeros requisitos es el lenguaje homoicónico. Como mínimo, querrá que su lenguaje de programación central sea lo más pequeño posible para que cuando ingrese al sistema y comience a hacer que se interprete, funcionará. Por lo tanto, desea un intérprete metacircular que fue pionero en lisp. Otros idiomas también lo han hecho, pero existe una enorme cantidad de investigación existente sobre lisp.
El primer paso si desea hacer esto es tener un lenguaje homoicónico como Lisp o algún marco en el que pueda razonar sobre un programa en ejecución. Lisp se utiliza para esto por la única razón de que podría definir un intérprete metacircular en el idioma o simplemente puede tratar su código como datos. Tratar el código como datos es lo más importante. A lo largo de la discusión sobre lo que significa homoicónico en c2 wiki.
Por ejemplo, en Lisp, su tipo de datos "Programa" son programas lisp válidos. Pasa los programas lisp a un intérprete y este calcula algo. El intérprete lo rechaza si no programa un "Programa" válido.
Por lo tanto, un lenguaje homoicónico cumple tres de sus requisitos. Incluso en lisp puedes definir la idea de un programa formal.
¿Puedes modelar lisp dentro de lisp? Sí, esto se hace con frecuencia principalmente como un ejercicio al final de un libro de programación de lisp para probar sus habilidades. SICP
En este momento, el número cuatro es una pregunta de investigación y a continuación se encuentra lo que he encontrado que intenta responder a esta pregunta.
Diría que hay muchos tipos de programas que intentan hacer esto. A continuación se muestran todos los programas que conozco.
JSLint es un ejemplo de analizadores estáticos que toman código de máquina u otro lenguaje y buscan errores explícitamente. Luego le pide a un programador que corrija eso.
Coq es un entorno que le permite especificar pruebas utilizando un lenguaje de programación. También tiene tácticas donde sugiere formas para resolver el problema. Aún así, esto espera que un humano haga el trabajo. Coq utiliza tipos dependientes para trabajar y, por lo tanto, es muy teórico de tipos. Es muy popular entre los informáticos y las personas que trabajan en la teoría de los tipos de homotopía.
ACL2, por otro lado, es un comprobador de teoremas automatizado. Este sistema probará declaraciones basadas en algo que usted programe.
ACL2 y Coq tienen un complemento de software que interconecta su sistema con un sistema de aprendizaje automático . Lo que se usa para entrenar estos sistemas son programas escritos previamente. Según tengo entendido, estos sistemas agregan otra característica en la que no solo tiene sus tácticas, sino que sugiere teoremas que ayudan en el desarrollo de pruebas.
A continuación se muestra más de lo que significa su pregunta.
fuente
Como la respuesta de @ user217281728 menciona que hay un tipo de máquinas relacionadas más con la inferencia y la IA, llamadas Máquinas Gödel
La publicación de referencia de Jürgen Schmidhuber sobre "Máquinas Goedel: solucionadores de problemas universales auto-referenciales que hacen auto-mejoras probables óptimas", (2006) arXiv: cs / 0309048v5
La forma en que funciona la máquina para implementar metaaprendizaje tiene dos fases:
Como la máquina modifica su propia fuente, es autorreferencial, es decir, tiene la propiedad de auto modificación (ver también aquí ).
En este sentido, puede modificar el algoritmo de aprendizaje en sí mismo en un sentido riguroso (demostrando una auto-modificación óptima). Existen los problemas de autorreferencia e indecidibilidad que en este caso toman la forma:
Otros idiomas (y sus máquinas de intérprete asociadas) que tienen la propiedad de auto modificación son, por ejemplo, LISP .
En el código LISP y los datos son intercambiables, o el código fuente AST está disponible como datos, en el programa LISP y puede modificarse como datos. Por otro lado, los datos pueden verse como AST, para algún código fuente.
actualizar
También hay otras máquinas , como las máquinas de autoprogramación (entre otras) que combinan autorreferencia , autorreproducción y autoprogramación .
Un aspecto interesante de lo anterior es que la autorreferencia no es problemática en absoluto, sino que es un elemento necesario en la autorreproducción / autómatas auto-programación .
Para más detalles (y más publicaciones) consulte JP Moulin, CR Biologies 329 (2006)
resumen
fuente
Este artículo de Jurgen Schmidthuber podría ser de interés:
http://arxiv.org/pdf/cs/0309048.pdf
fuente