Tu programa tiene que leer expresiones lambda y saber realizar 3 operaciones básicas del lambda cálculo: calcular las variables “gastadas”, calcular las variables libres, y realizar substituciones.
El lenguaje de las expresiones lambda (expresiones a partir de ahora) se describe con los siguientes tres casos y con ninguno más:
Cadenas de caracteres de la 'a' a la
'z' son expresiones (variables).
Dada una expresión
y una variable
,
la cadena formada por el caracter '\', seguido de
,
seguido del caracter '.' seguido de
($\verb|\|v\verb|.|B$) es una expresión
(abstracción).
Dadas dos expresiones
y
,
la cadena formada por el caracter '(', seguido de
,
seguido del caracter ' ' (blanco), seguido de
,
seguido del caracter ')' ($\verb|(|F\verb| |A\verb|)|$) es una
expresión (aplicación).
El conjunto de variables gastadas
de una expresión
es el conjunto de todas las variables de la 'a' a la
'z' que aparecen en la expresión
,
de cualquier forma. Equivalentemente, $$VG(E)=
\left\{
\begin{array}{ll}
\{v\} & \textbf{Si } E = v\\
VG(B) \cup \{v\} & \textbf{Si } E = \verb|\|v\verb|.|B\\
VG(F) \cup VG(A) & \textbf{Si } E = \verb|(|F\verb|
|A\verb|)|\\
\end{array}
\right.$$
El conjunto de variables libres de una expresión se define de esta forma: $$VL(E) = \left\{ \begin{array}{ll} \{v\} & \textbf{Si } E = v\\ VL(B) - \{v\} & \textbf{Si } E = \verb|\|v\verb|.|B\\ VL(F) \cup VL(A) & \textbf{Si } E = \verb|(|F\verb| |A\verb|)|\\ \end{array} \right.$$
La substitución de una variable en una expresión por otra expresión se define de la siguiente forma:
$$E[x := E'] = \left\{ \begin{array}{ll} v & \textbf{Si } E \textrm{\ es una variable $v$ distinta de $x$ }\\ E' & \textbf{Si } E = x\\ \verb|\|v\verb|.|B & \textbf{Si } E = \verb|\|v\verb|.|B \textrm{ y } v=x \\ \verb|\|v\verb|.|B[x := E'] & \textbf{Si } E = \verb|\|v\verb|.|B \textrm{, } v\neq x \textrm{ y } v \not\in VL(E')\\ \verb|(|F[x := E']\verb| |A[x := E']\verb|)| & \textbf{Si } E = \verb|(|F\verb| |A\verb|)|\\ \end{array} \right.$$
Observad que, cuando es de la forma $\verb|\|v\verb|.|B$, no siempre es posible realizar la substitución. Esto siempre puede corregirse aplicando una conversión alpha, descritas a continuación, en la expresión $\verb|\|v\verb|.|B$ reemplazando por una variable no gastada. Sin embargo, las entradas del problema serán tales que nunca os va a ser necesario hacer una conversión alpha para hacer la substitución.
Un juego de pruebas es una secuencia de cálculos, cada uno de los
cuales ocupa una línea. Los cálculos pueden ser de la forma
“G
”,
“L
”
o “S
”,
donde
y
son expresiones válidas y
es una variable. Ninguna de las líneas ocupará más de 2000 caracteres.
En los cálculos de tipo S se os garantiza que la
substitución puede hacerse, sin que sea necesario que hagáis ninguna
conversión alpha en ningún momento.
Por cada cálculo, tu programa debe escribir una línea con la
respuesta. Escribe las variables gastadas
de
si la petición es de tipo G, las variables libres
de
si es de tipo L, y la substitución
si la petición es de tipo S. Escribe un conjunto de
variables como una secuencia ordenada alfabéticamente de las mismas
(fíjate en los ejemplos). Observa que el resultado de la substitución
puede ser más largo de 2000 caracteres.
TestA:
Pruebas de no más de 200 expresiones que sólo contienen peticiones de
cálculo de tipo G.
TestA:
Pruebas de no más de 200 expresiones que sólo contienen peticiones de
cálculo de tipo L.
TestA:
Pruebas de no más de 200 expresiones que sólo contienen peticiones de
cálculo de tipo S.
Si sois capaces de resolver este problema, estáis muy cerca de poder evaluar expresiones lambda. A continuación describimos los pasos necesarios.
El cambio en el nombre de la variable en expresiones de la forma $\verb|\|v\verb|.|B$ crea expresiones equivalentes.
Cualquier expresión de la forma
(\. )
se reduce a
,
donde puede haber sido necesario aplicar una conversión alpha sobre
.
renombrando
en una variable no gastada.
Una expresión se dice que está en forma normal cuando no pueden aplicarse más reducciones beta a ninguna de sus subexpresiones.
Input
G x G \x.(x \y.(x y)) G (x y) G \x.(x y) G (\x.x f) G (\x.(x \x.x) f) G (\y.\x.y x) G (((\c.\t.\e.((c t) e) \a.\b.a) a) b)
Output
x xy xy xy fx fx xy abcet
Input
L x L \x.(x \y.(x y)) L (x y) L \x.(x y) L (\x.x f) L (\x.(x \x.x) f) L (\y.\x.y x) L (((\c.\t.\e.((c t) e) \a.\b.a) a) b)
Output
x xy y f f x ab
Input
S x x y S y y y S x x (x z) S x (x x) (x z) S x (x (y x)) (\x.(f f) g) S x \x.x (a a) S x \y.x (a a) S x \y.(x \x.(x x)) (a z)
Output
y y (x z) ((x z) (x z)) ((\x.(f f) g) (y (\x.(f f) g))) \x.x \y.(a a) \y.((a z) \x.(x x))