Estoy buscando un cálculo simple que admita el razonamiento sobre la reflexión , a saber, la introspección y la manipulación de programas en ejecución.
¿Existe una extensión de cálculo tipo que permita convertir los términos λ en una forma que pueda ser manipulada sintácticamente y luego evaluada?
Me imagino que el cálculo tiene dos términos adicionales principales:
- : toma v y produce una representación de v modificable a la manipulación sintáctica.
- : toma una representación sintáctica de un término y lo evalúa.
Para apoyar la reflexión, se requiere una representación sintáctica de los términos. Se vería algo así como:
- se representaría como un término ( L A M R ( e ) ) , donde R ( e ) es la versión reflejada de e ,
- se representaría como término ( A P P R ( e ) R ( e ' ) ) , y
- se representaría como ( V A R x ) .
Con esta representación, la coincidencia de patrones podría usarse para manipular términos.
Pero nos encontramos con un problema. y e v a l deben codificarse como términos, al igual que la coincidencia de patrones. Tratar con esto parece ser sencillo, agregando R E F L E C T , E V A L y M A T C H , pero ¿tendré que agregar otros términos para respaldar la manipulación de estos?
Hay opciones de diseño que deben hacerse. ¿Qué debe hacer la función aludida anteriormente con el cuerpo de r e f l e c t y e v a l ? ¿Debería R ( - ) transformar el cuerpo o no?
Como no estoy tan interesado en estudiar la reflexión misma, el cálculo serviría como vehículo para otras investigaciones, no quiero reinventar la rueda.
¿Hay algún cálculo existente que coincida con lo que acabo de describir?
Por lo que puedo decir, los cálculos como MetaML, sugeridos en un comentario, son muy útiles, pero no incluyen la capacidad de emparejar patrones y deconstruir fragmentos de código que ya se han construido.
Una cosa que me gustaría poder hacer es lo siguiente:
Y luego realice una coincidencia de patrones en el resultado para construir una expresión completamente diferente.
Ciertamente, esta no es una extensión conservadora del cálculo y es probable que la metateoría sea fea, pero este es el punto para mi aplicación. Quiero separar las abstracciones λ .
fuente
Respuestas:
Jean Louis Krivine introdujo un cálculo abstracto que extiende la "Máquina Krivine" de una manera muy trivial (tenga en cuenta que la máquina Krivine ya admite la instrucción call / cc de lisp):
Introduce un operador de "cita" en este artículo definido de la siguiente manera: si es un término λ , tenga en cuenta n ϕ la imagen de ϕ mediante alguna biyección π : Λ → N de términos lambda a números naturales. Nota ¯ n el número iglesia que corresponde a n ∈ N . Krivine define el operador χ por la regla de evaluación: χ ϕ → ϕ ¯ n ϕϕ λ nϕ ϕ π:Λ→N n¯¯¯ n∈N χ
Tenga en cuenta que Krivine es muy difícil de leer (¡por favor, no se enoje si lee esto, Jean-Louis!), Y algunos investigadores han realizado el acto caritativo de tratar de extraer el contenido técnico de una manera más legible. Puede intentar echar un vistazo a estas notas de Christophe Raffali.
¡Espero que esto ayude!
Se me ocurre que hay otra referencia que puede ser relevante para sus intereses: el Cálculo de Patrón Puro de Jay y Kesner formaliza una variante del cálculo que extiende la abstracción simple sobre una variable a una abstracción sobre un patrón que representa un cálculo de patrón sí mismo. Esto es fenomenalmente expresivo y, en particular, le permite a uno deconstruir una aplicación en sí: si no me equivoco, el término:λ
se reduce a . Una vez más, creo que esto es más que suficiente para implementar los operadores de cotización y evaluación .λx.x x
fuente
Hacerlo es muy difícil, si no imposible, sin renunciar a la confluencia. Es decir, sospecho que tienes razón sobre una meta-teoría peluda. Por otro lado, es posible diseñar un cálculo combinador que pueda expresar todas las funciones computables de duración, y que tenga la capacidad total de inspeccionar sus términos: ver Jay y Give-Wilson .
Sin embargo, creo que tener esta habilidad hace algunas cosas malas a su teoría de la ecuación. En particular, tenderá a ser capaz de demostrar que dos valores son iguales si son iguales hasta las equivalencias alfa.
Todavía no he leído el documento de Krivine vinculado a Cody, pero debo tener en cuenta que en la lógica clásica esencialmente solo tienes dos cosas: verdadero y falso. Todo es equivalente a uno de esos. Es decir, tiende a tener una teoría de la ecuación colapsada de todos modos.
fuente
En la teoría de los lenguajes de programación, la característica de la que habla suele denominarse "cita". Por ejemplo, John Longley escribió sobre esto en algunos de sus trabajos, vea este documento .
Si solo busca consideraciones teóricas (en oposición a una implementación realmente útil), puede simplificar las cosas al indicar que
quote
(oreflect
como lo llama) se mapea en el tipo de enterosnat
al devolver un código Gödel de su argumento. Luego puede descomponer el número tal como lo haría con un árbol de sintaxis abstracta. Además, no es necesarioeval
porque eso se puede implementar en el idioma, es esencialmente un intérprete para el idioma.Para un modelo concreto que tenga estas características, puede considerar el primer álgebra combinatoria de Kleene: interprete todo como un número (piense en ellos como códigos de Gödel) y defina la aplicación de Kleene para que signifique φ n ( m ) donde φ n es el n - La función parcial. Esto le dará un modelo de cálculo λ (con mapas parciales) en el cual es simplemente la función de identidad. No es necesario agregar más funciones al idioma.n⋆m φn(m) φn n λ
quote
Si me dices lo que buscas, podría darte referencias más específicas.
Por cierto, aquí hay un problema abierto:
La reglaξ
quote
quote
quote
is supposed to calculate "very canonical" Gödel codes – but even assuming we have a typedfuente
quote
must be a congruence for all the rules ofHere is an alternative answer, instead of using my nominal approach which is still experimental there is some more established approach that goes back to the paper:
LEAP: A language with eval and polymorphism
Frank Pfenning and Peter Lee
https://www.cs.cmu.edu/~fp/papers/tapsoft89.pdf
The paper starts with:
Please note that LEAP is much stronger than what the OP wants. First of all it is typed. And second it asks for metacircularity, which means for example that eval can execute its own definition. In Prolog you get metacircularity for solve/1:
If you add the following clause to solve/1:
And if you see to it that clause/2 also returns the clauses of solve/1. You can then call solve(solve(...)) and see how solve executes itself.
Questions of self representatio still spurr some research, see for example:
Self representation in Girards System U
Matt Brown, Jens Palsberg
http://compilers.cs.ucla.edu/popl15/popl15-full.pdf
fuente
The problem is identified in vincinity of proof assistants such as Coq and Isabelle/HOL. It goes under the acronym HOAS. There are some claims around λ-Prolog that through the new ∇ quantifier such things can be done. But I couldn't get a grip yet of this claim. I guess the main insight I got so far is that there is no definite approach, there are a couple of possible approaches.
My own take, not yet finished, is inspired by a recent paper by Paulson on proving Gödels incompletness. I would use the object-level binders in connection with some data structure that has the meta-level names. Basically a similar yet distinct data structure as the one from the OP, and with Church coding since I am interested in dependent types:
The meta level expressions can be distinguished from the object level expressions in that we use the variable names n, m, .. etc.. to denote names. Whereas we use the variable names x, y, .. etc.. on the object level. The interpretation of a meta term in the object logic would then work as follows. Lets write [t]σ for the interpretation of the nominal term t in the nominal context σ, which should give an object term. We would then have:
The above would define what the OP calls an EVAL function. Small difference to Paulson, σ is only a finite list and not a functional. In my opinion it would be only possible to introduce an EVAL function and not a REFLECT function. Since on the object level you might have some equality so that different lambda expressions are the same. What you have to do would be to use eval to reason possibly also about reflection if you feel the need.
You would need to go to extremes like Prolog where nothing is expanded, if you want to tear down the wall between nominal and non-nominal. But as the λ-Prolog system example shows, in the higher-order case there are luring additional problems which can for example only be overcome in logical way by introducing new means such as a ∇ quantifier!
fuente