• No se han encontrado resultados

4. FLC: una sem´ antica operacional de bajo nivel

4.2. Relaci´ on con CRWL

5.1.1. Sintaxis de la let reescritura

Para introducir estas ligaduras locales extendemos el conjunto Exp de CRWL-expresiones a˜nadiendo una nueva construcci´on sint´actica let. Para conseguir distinguir claramente las variables ligadas por una expresi´on let del resto de variables, consideramos el conjunto V de variables disponibles dividido en dos subconjuntos disjuntos, V = P V ar ] F V ar, donde P V ar es el conjunto de variables producidas (ligadas en construcciones let ) y F V ar el resto de variables, que son siempre libres. Cuando sea necesario marcaremos las variables producidas con un sub´ındice “p” para evitar confusiones. Formalmente, la

sintaxis de las let-expresiones es:

1Seg´un es habitual, por indeterminismo don’t know nos referimos al indeterminismo introducido por

las reglas de un c´alculo en el que no se sabe qu´e regla del c´alculo hay que elegir en un cierto punto. Se contrapone al indeterminismo don’t care, en el que cualquier elecci´on es buena.

80 5. Let-reescritura

Definici´on 5.1.1 (let -expresiones). Definimos el conjunto de let-expresiones, LExp como

LExp 3 e ::= X | h(e) | let Xp= e1 in e2

donde X ∈ V, h ∈ CS∪F S y Xp ∈ P V ar. A menudo usaremos la notaci´on let Xp = a in e

como abreviatura de let Xp1 = a1 in . . . let Xpn = an in e.

N´otese tambi´en que la noci´on de c-t´ermino no ha cambiado con la introducci´on de los let’s: los c-t´erminos no pueden contener let’s, pero en particular pueden contener variables producidas. Es por ello que resultar´a ´util definir el conjunto F CT erm de c-t´erminos construidos sin usar variables de PVar, porque estos corresponder´an a c-t´erminos totales sea cual sea el contexto en el que se encuentren, mientras que un c-t´ermino con variables producidas (al introducirse en el contexto apropiado) podr´ıa corresponder a una expresi´on en la mitad de su evaluci´on.

Definici´on 5.1.2 (Contextos). La noci´on de contexto con un solo hueco tambi´en es extendida a la nueva sintaxis. El conjunto Cntxt de contextos con un solo hueco se define como:

Cntxt 3 C ::= [] | let Xp = C in e | let Xp= e in C | h(. . . , C, . . .)

Definici´on 5.1.3 (Sustituciones y variables libres y ligadas). La introducci´on de la nueva construcci´on sint´actica let extiende el conjunto Subst al conjunto LSubst de aplicaciones de V en LExp. Por su parte, los conjuntos F V (e) y BV (e) de variables libres y variables ligadas de e ∈ LExp se definen como:

F V (X) = {X} F V (h(e)) =S ei∈eF V (ei) F V (let Xp = e1 in e2) = F V (e1) ∪ (F V (e2)\{Xp}) BV (X) = ∅ BV (h(e)) =S ei∈eBV (ei) BV (let Xp = e1 in e2) = BV (e1) ∪ BV (e2) ∪ {Xp}

N´otese que esta definici´on de F V , en particular el caso para la construcci´on let, implica que no se utilizar´an let’s recursivos en este formalismo, ya que para let Xp =

e1 in e2 las posibles apariciones de Xp en e1 no son consideradas ligadas y por tanto se

refieren a un Xp ‘distinto’. Esto es similar a lo que se hace en [MOW98,SH04], pero no

en [Lau93, AHH+05]. Los let’s recursivos tienen inter´es por s´ı mismos pero al no estar presentes en los CRWL-programas (ya que en CRWL no hay let’s en absoluto) ni aparecer en las reducciones de let -reescritura (que definiremos m´as adelante), hemos decidido no considerarlos2.

2Adem´as todav´ıa no hay un consenso sobre la interpretaci´on m´as conveniente que debe hacerse de los

let’s recursivos en presencia de indeterminismo [Han02]. Por ejemplo, dado el programa de la p´agina79, ¿cual deber´ıa ser la denotaci´on de la expresi´on let X = coin : X in heads(X)?. La cuesti´on se complica a´un m´as si tenemos en cuenta let’s mutuamente recursivos como let {C = coin; X = C : Y ; Y = C : X} in X. Varias opciones son posibles en estos casos de forma similar a como ocurre con elecci´on en invocaci´on y la elecci´on en ejecuci´on.

5.1.1 Sintaxis de la let-reescritura 81

Tambi´en ser´a ´util en ocasiones considerar el conjunto de todas las variables de una let - expresi´on, sean estas ligadas o libres. Nos referiremos a ese conjunto mediante V (e) = F V (e) ∪ BV (e).

Como es habitual en las construcciones sint´acticas con ligaduras de variables, asumiremos una convenci´on de variables seg´un la cual las variables ligadas pueden ser renombradas de forma consistente de manera que se asegure que el mismo s´ımbolo de variable no aparezca a la vez libre y ligado dentro de una misma expresi´on. Adem´as, para simplificar el manejo de las substituciones, supondremos que cuando una sustituci´on θ se aplique a una expresi´on e ∈ LExp, e ha sido renombrado de forma que BV (e) ∩ (dom(θ) ∪ vRan(θ)) = ∅. Bajo estas suposiciones las reglas de aplicaci´on de sustituciones son sencillas y a la vez aseguran que se ha evitado la captura de variables:

Xθ = θ(X)

h(e1, . . . , en)θ = h(e1θ, . . . , enθ)

(let X = e1 in e2)θ = let X = e1θ in e2θ

As´ı durante todo el trabajo se consideran equivalentes sint´acticamente los renombramien- tos de let -expresiones mediante α-conversi´on.

Y terminando con las sustituciones, podemos demostrar que se cumple el siguiente lema de sustituci´on, un resultado est´andar que siempre es ´util y que resulta de la adaptaci´on del lema de sustituci´on del λ-c´alculo, i.e. M [x := N ][y := P ] = M [y := P ][x := N [y := P ]], si x 6= y y x 6∈ var(P ). Para este lema emplearemos los conjuntos LExp⊥ y LSubst⊥ que

se definen a˜nadiendo ⊥ a sus versiones totales, como si fuera una constructora de aridad cero. Aunque como veremos m´as adelante la let -reescritura no utiliza el valor sem´antico ⊥, ´

este s´ı es empleado por otros c´alculos que comparten la parte total de su sintaxis, c´alculos que utilizaremos en secciones posteriores.

Lema 5.1.1 (Lema de sustituci´on para el c´alculo let ). Dados e, e0 ∈ LExp⊥, θ ∈

LSubst⊥ y X ∈ V tal que X 6∈ dom(θ) y X 6∈ vRan(θ), entonces se tiene que:

(e[X/e0])θ ≡ eθ[X/e0θ] Demostraci´on. Por inducci´on sobre la estructura de e:

e ≡ X: Entonces

(e[X/e0])θ ≡ (X[X/e0])θ ≡ e0θ ≡ X[X/e0θ] ≡X6∈dom(θ)Xθ[X/e0θ] ≡ eθ[X/e0θ]

e ≡ Y 6≡ X: Entonces

(e[X/e0])θ ≡ (Y [X/e0])θ ≡ Y θ ≡X6∈ran(θ)Y θ[X/e0θ] ≡ eθ[X/e0θ] e ≡ h(e1, . . . , en): Entonces

(e[X/e0])θ ≡ (h(e1, . . . , en))[X/e0]θ ≡ h(e1[X/e0]θ, . . . , en[X/e0]θ)

82 5. Let-reescritura

e ≡ let Y = e1 in e2: Entonces

(e[X/e0])θ ≡ (let Y = e1 in e2)[X/e0]θ ≡ let Y = e1[X/e0]θ in e2[X/e0]θ

≡HI let Y = e1θ[X/e0θ] in e2θ[X/e0θ] ≡ (let Y = e1 in e2)θ[X/e0θ]

≡ eθ[X/e0θ]

Otro lema interesante relativo a las aplicaciones de sustituciones sobre contextos: Lema 5.1.2. Para todo θ ∈ CSusbst⊥, C ∈ Cntxt y e ∈ LExp⊥ tales que dom(θ) ∩

BV (C) = vRan(θ) ∩ BV (C) = ∅ se tiene que (C[e])θ ≡ Cθ[eθ]. Demostraci´on. Por inducci´on en la estructura de C :

Caso base :

C ≡ []: entonces C[e] ≡ e, por tanto (C[e])θ ≡ eθ ≡ []θ[eθ] ≡ Cθ[eθ] Paso inductivo :

C ≡ let Xp = C0 in e1: por tanto C[e] ≡ let Xp= C0[e] in e1. Entonces

(C[e])θ ≡ let Xp= (C0[e])θ in e1θ ≡IH let Xp = C0θ[eθ] in e1θ

≡ (let Xp= (C0[])θ in e1θ)[eθ] ≡(∗) ((let Xp = C0[] in e1)θ)[eθ] ≡ Cθ[eθ]

(∗): podemos dar este ´ultimo paso porque gracias a la hip´otesis podemos ase- gurar que no ser´a necesario ning´un renombramiento para aplicar (let Xp =

C0[] in e 1)θ.

C ≡ let Xp = e1 in C0: por tanto C[e] ≡ let Xp= e1 in C0[e]. Entonces

(C[e])θ ≡ let Xp= e1θ in (C0[e])θ ≡IH let Xp = e1θ in C0θ[eθ]

≡ (let Xp= e1θ in (C0[])θ)[eθ] ≡(∗) ((let Xp = e1 in C0[])θ)[eθ] ≡ Cθ[eθ]

(∗): podemos dar este ´ultimo paso porque gracias a la hip´otesis podemos ase- gurar que no ser´a necesario ning´un renombramiento por para aplicar (let Xp=

e1 in C0[])θ.

C ≡ h(. . . , C0, . . .): por tanto C[e] ≡ h(. . . , C0[e], . . .). Entonces

(C[e])θ ≡ h(e1θ, . . . , (C0[e])θ, . . . , enθ) ≡IH (e1θ, . . . , C0θ[eθ], . . . , enθ) ≡ Cθ[eθ]

N´otese que sin la hip´otesis dom(θ) ∩ BV (C) = vRan(θ) ∩ BV (C) = ∅ este lema ser´ıa falso, como podemos ver en los siguientes contraejemplos:

C[] ≡ let Xp = 1 in [] e ≡ Xp+ 2

θ = [Xp/3]

(C[e])θ ≡ C[e] ≡ let Xp= 1 in Xp+ 2

5.1.1 Sintaxis de la let-reescritura 83 y C[] ≡ let Xp = 1 in [] e ≡ Xp+ Y θ = [Y /Xp] (C[e])θ ≡ let Zp = 1 in Zp+ Xp

Cθ[eθ] ≡ ((let Xp= 1 in [])[Y /Xp])[(Xp+ Y )[Y /Xp]]

≡ (let Zp = 1 in [])[Xp+ Xp] ≡ let Zp= 1 in Xp+ Xp

La noci´on de c´ascara, como en CRWL, se refiere a la parte ya calculada de una expre- si´on, y se define en el marco de la let -reescritura ampliando la definici´on existente con el caso para la construcci´on let, como sigue:

Definici´on 5.1.4 (C´ascara de una expresi´on).

|X| = X

|c(e1, . . . , en)| = c(|e1|, . . . , |en|), si c ∈ CS

|f (e1, . . . , en)| = ⊥ , si f ∈ F S

|let Xp = e1 in e2| = |e2|[Xp/|e1|]

N´otese que la informaci´on contenida en las ligaduras de los let’s se tiene en cuenta a la hora de construir la c´ascara. Por ejemplo |c(let Xp = 2 in s(Xp))| = c(s(2)).

El siguiente lema enuncia una propiedad sencilla de las c´ascaras respecto a las susti- tuciones:

Lema 5.1.3. Para todo e1, e2∈ LExp, X ∈ V, |e1[X/e2]| ≡ |e1|[X/|e2|]

Demostraci´on. Por inducci´on en la estructura de e1:

e1≡ X: |e1[X/e2]| ≡ |X[X/e2]| ≡ |e2| ≡ X[X/|e2|] ≡ |X|[X/|e2|] ≡ |e1|[X/|e2|]

e1≡ Y 6≡ X:

|e1[X/e2]| ≡ |Y [X/e2]| ≡ |Y | ≡ Y

≡ Y [X/|e2|] ≡ |Y |[X/|e2|] ≡ |e1|[X/|e2|]

e1≡ c(s1, . . . , sn):

|e1[X/e2]| ≡ |c(s1[X/e2], . . . , sn[X/e2])| ≡ c(|s1[X/e2]|, . . . , |sn[X/e2]|)

≡HI c(|s1|[X/|e2|], . . . , |sn|[X/|e2|]) ≡ c(|s1|, . . . , |sn|)[X/|e2|]

≡ |c(s1, . . . , sn)|[X/|e2|] ≡ |e1|[X/|e2|]

e1 ≡ let Y = s1 in s2: Entonces por la convenci´on de variables Y 6∈ dom([X/e2]) y

Y 6∈ vRan([X/e2]). Luego:

|e1[X/e2]| ≡ |let Y = s1[X/e2] in s2[X/e2]|

≡ |s2[X/e2]|[Y /|s1[X/e2]|]

≡HI |s2|[X/|e2|][Y /(|s1|[X/|e2|])]

≡ |s2|[Y /|s1|][X/|e2|] (*) ≡ |let Y = s1 in s2|[X/|e2|] ≡ |e1|[X/|e2|]

84 5. Let-reescritura

Cuando tratemos con variantes de reglas de programa (l → r) ∈ P supondremos siempre que l → r es una variante fresca de la regla del programa en el sentido de que sus variables sean diferentes de las de la expresi´on siendo evaluada. Tambi´en impondremos que ninguna variable producida pueda aparecer en una instancia de regla de programa, esto es posible porque estamos trabajando con CRWL-programas, en los que no aparece expresi´on let alguna: todos los let’s son introducidos por las reglas del c´alculo.

Definici´on 5.1.5 (c-instancia total de reglas de programa). Denotamos y definimos el conjunto de c-instancias totales de reglas de un CRWL-programa P como:

[P]= {(l → r)σ | (l → r) ∈ P, σ ∈ CSubst}

Seg´un esta definici´on de c-instancia los valores de σ para las variables extra son elegi- dos libremente, como es habitual en la reescritura tradicional cuando se permiten variables extra en los TRS’s. En particular esto nos permite instanciar variables extra con varia- bles producidas, lo que nos puede llevara situaciones que en un principio podr´ıan parecer inc´omodas, pero que resultar´an ser inofensivas, como veremos en el pr´oximo apartado. 5.1.2. Reglas de la let -reescritura

En la figura5.2 podemos ver las reglas que definen la relaci´on de let -reescritura, que denotaremos con el s´ımbolo →l.

(Contx) C[e] →l C[e0], si e →l e0, C ∈ Cntxt

(Elim) let Xp = e1 in e2→le2, si Xp no aparece libre en e2

(Bind) let Xp = t in e →l e[Xp/t], si t ∈ CT erm

(Flat) let Xp = (let Yp = e1 in e2) in e3 →l let Yp = e1 in (let Xp = e2 in e3)

si Yp no aparece libre en e3

(LetIn) h(. . . , e, . . .) →l let Xp = e in h(. . . , Xp, . . .)

si h ∈ CS ∪ F S, e es de la forma e ≡ f (e0) con f ∈ F S ´o e ≡ let Yp = e0 in e00, y con Xp ∈ P V ar fresca

(Fapp) f (t1, . . . , tn) →l r, si (f (t1, . . . , tn) → r) ∈ [P]

Figura 5.2: Reglas de la let -reescritura

La regla (Contx) nos permite seleccionar cualquier subexpresi´on como redex para la derivaci´on. (Fapp) es la regla que realiza el paso de reescritura propiamente dicho, usando una regla de programa. Al utilizar c-instancias totales de reglas de programa para dar dicho paso, es decir, solamente c-sustituciones totales sobre variantes de las reglas de programa, evitamos la copia de expresiones sin evaluar, lo que destruir´ıa el sharing y la elecci´on en invocaci´on. Pero si solamente hici´eramos esto tendr´ıamos una sem´antica estricta, por lo que introducimos la regla (LetIn) que nos permite suspender la evaluaci´on de una expre- si´on introduci´endo una ligadura let. De esta manera si dicha expresi´on es argumento de un s´ımbolo de funci´on, tras aplicar (LetIn) una variable producida fresca ocupar´a su lugar en la aplicaci´on de funci´on, con lo que tras varias posibles aplicaciones de (LetIn) sobre sus argumentos se podr´a reescribir dicha aplicaci´on de funci´on mediante (Fapp). La ventaja