Combinadores SK

26
1 Combinadores SK

description

Combinadores SK. Introducción. Examinaremos una técnica de reducción de grafos basada en un conjunto fijo de supercombinadores. Entre ellos, S y K son los combinadores más importantes. - PowerPoint PPT Presentation

Transcript of Combinadores SK

Page 1: Combinadores SK

1

Combinadores SK

Page 2: Combinadores SK

2

Introducción

Examinaremos una técnica de reducción de grafos basada en un conjunto fijo de supercombinadores. Entre ellos, S y K son los combinadores más importantes.

Este método posibilita la definición de una muy simple máquina de reducción: maneja operadores primitivos y no necesita un mecanismo de instanciación.

La implementación de esta máquina puede llegar a ser más perezosa que una que incorpore los mecanismos descriptos hasta ahora, pero a un costo considerable.

Page 3: Combinadores SK

3

Esquema de compilación SK

Nuestra estrategia será transformar un programa funcional en uno que sólo contenga constantes y operadores primitivos, además de los combinadores S, K e I.

Las reglas de reducción de estos combinadores es como sigue:

S f g x -> f x (g x)

K x y -> x

I x -> x

S, K e I son supercombinadores, pero usaremos el término más general de combinador para nombrarlos.

Page 4: Combinadores SK

4

Introduciendo S, K e I

Consideremos las siguientes expresiones:

Fun = \ x -> e1 e2 Fun’ = S (\ x -> e1) (\ x -> e2)

Podemos demostrar que Fun y Fun’ son extensionalemente iguales.

Transformaci’on S:

\ x -> e1 e2 => S (\ x -> e1) (\ x -> e2)

Usamos => para denotar “compilación”.

Page 5: Combinadores SK

5

Transformación S

Ejemplo: h = \ x -> Or x True

\ x -> Or x True

S => S (\ x -> Or x) (\ x -> True)

S=> S (S (\ x -> Or) (\ x -> x)) (\ x -> True)

Cada vez que aplicamos la transformación S el \ x es empujado un nivel hacia abajo, ya que mientras el cuerpo sea una aplicación este tipo de transformación puede ser efectuado.

Por otro lado, en cada aplicación de la transformación dos nuevas abstracciones son generadas. Al final los cuerpos de estas abstracciones serán atomicos y entonces tendremos que considerar los siguientes dos casos:

Page 6: Combinadores SK

6

Transformación I

i) La expresión es \ x -> x.

Esta expresión es la función identidad, la que hemos definido como el combinador I.

La transformación I reemplaza \ x -> x con I, entonces

Transformación I:

\ x -> x => I

S (S (\ x -> Or) (\ x -> x)) (\ x -> True)

I => S (S (\ x -> Or) I) (\ x -> True)

Page 7: Combinadores SK

7

Transformación K

ii) La expresión es de la forma \ x -> c, donde c es una constante o una variable distinta de x. Este tipo de funciones toman un argumento, lo descartan y retornan c, por lo tanto podemos reemplazarlas por espresiones de la forma (K c)

Transformación K : \ x -> c => K c

Como en el caso de S, se puede fácilmente demostrar que estas dos expresiones son extensionalmente iguales.

S (S (\ x -> Or) I) (\ x -> True)

K => S (S (K Or) I) (K True)

Page 8: Combinadores SK

8

Reglas de traducción y transformación

Para resumir, hemos presentado reglas de transformación y reducción para los combinadores S, K e I, las que desplegamos en conjunto a continuación:

reducción S S f g x -> f x (g x)

reducción K K x y -> x

reducción I I x -> x

transformación S \ x -> e1 e2 => S (\ x -> e1) (\ x -> e2)

transformación K \ x -> c => K c (c x)

transformación I \ x -> x => I

Page 9: Combinadores SK

9

Reglas de traducción y transformación (2)

Podemos usar las reglas de reducción para evaluar el programa resultado de aplicar las transformaciones:

h x

= S (S (K Or) I) (K True) x

S -> S (K Or) I x (K True x)

S -> K Or x (I x) (K True x)

K -> Or (I x) (K True x)

I -> Or x (K True x)

K -> Or x True

Page 10: Combinadores SK

10

Compilación e implementación

Las transformaciones que hemos presentado constituyen un algortimo completo de compilación, el que transforma cualquier expresión lambda en una que sólo consiste de combinaciones de los combinadores y constantes.

El siguiente es el algoritmo de compilación SK para compilar una expresión e:

Mientras e contenga una abstracción hacer (1) Elija cualquier abstracción innermost

(2) Si el cuerpo es una aplicación, aplique

la transformación S

(3) Si no, el cuerpo debe ser una variable o

una constante, aplique la transformación

K o I según corresponda.

Page 11: Combinadores SK

11

Compilación e implementación (2)

Ejemplo: (\ x -> + x x) 5

S => S (\ x -> + x) (\ x -> x) 5

S => S (S (\ x -> +) (\ x -> x)) (\ x -> x) 5

I => S (S (\ x -> +) I) (\ x -> x) 5

I => S (S (\ x -> +) I) I 5

K => S (S (K +) I) I 5

S (S (K +) I) I 5-> S (K +) I 5 (I 5)-> K + 5 (I 5) (I 5)-> + (I 5) (I 5)-> + 5 (I 5)-> + 5 5-> 10

Page 12: Combinadores SK

12

Compilación e implementación (3)Nombre Objeto sintáctico

e, e1, e2 expresiones

f, f1, f2 expresiones que no contienen abstracciones

x variable

cv constante

C [ e ] compila e a un combinador SK

C [ e1 e2 ] = C [ e1 ] C [ e2 ]

C [ \ x -> e ] = A x [ C [ e ] ]

C [ cv ] = cv

A x [ f ] abstrae x de f

A x [ f1 f2 ] = S (A x [ f1 ]) (A x [ f2 ])

A x [ x ] = I

A x [ cv ] = K cv

Page 13: Combinadores SK

13

Implementaciones

Los combinadores S, K, I son ejemplos particulares de supercombinadores, por lo tanto, la máquina de reducción que ejecuta código SK es una simplificación de una máquina de reducción de supercombinadores. El método para buscar el próximo redex unwinding la espina, el uso de un spine stack, y el uso de nodos de indirección todos se aplican también en esta máquina particular. Las principales diferencias son:

i) los combinadores son implementados directamente como operadores primitivos, no mecanismo general de instanciación de cuerpo para compilar el supercombinador.

ii) la máquina de reducción no tiene que implementar el mecanismo de instanciación.

Page 14: Combinadores SK

14

Instanciación perezosaUn programa compilado a combinadores SK ejecuta aún más

perezosamente que un programa supercombinador.

Consideremos:

$F x = If ec et ef , donde et y ef pueden ser expresiones muy grandes

Cuando $F es aplicada nuevas instancias de et y ef son construídas, aún cuando una de las dos será descartada.

Sin embargo, veamos que pasa cuando esta expresión es compilada usando combinadores SK y posteriormente aplicada a un argumento

Page 15: Combinadores SK

15

Instanciación perezosa (2)

\ x -> If ec et ef

S => S (\ x -> If ec et) (\ x -> ef)

S => S (S (\ x -> If ec) (\ x -> et)) (\ x -> ef)

S => S (S (S (\ x -> If) (\ x -> ec)) (\ x -> et)) (\ x -> ef)

... => S (S (S (K If) cc) ct) cf

Mostrar segmento inicial de secuencia de reducción (aplicada a x)

Notar que no se ha construído instancia de et o ef. Esta se ha pospuesto al construír las expresiones (ct x) y (cf x). Sólo la condición del If será evaluada.

S empuja el argumento un nivel hacia abajo dentro del cuerpo de la función.

Page 16: Combinadores SK

16

I no es necesario

En realidad sólo los combinadores S y K son suficientes para expresar el código combinatorio de una función, ya que el combinador I puede ser expresado en función de estos dos combinadores.

I = S K K

Sin embargo, toda implementación razonable incluye a I.

• Transformación de expresiones lambda en combinadores [Curry58]

• Técnica de implementación [Turner79]

Page 17: Combinadores SK

17

Optimización de los esquemas SK

Los ejemplos vistos muestran que el algoritmo de compilación tiende a generar expresiones combinatorias relativamente grandes a partir de simples abstracciones. De hecho, así como está definido el algoritmo de compilación es virtualmente inusable, ya que las expresiones obtenidas son muy grandes y su reducción a forma normal requiere muchos pasos de reducción.

Sin embargo, se pueden introducir optimizaciones al algoritmo de tal forma que la técnica sea efectivamente utilizable.

Para eso necesitaremos introducir algunos combinadores nuevos.

Page 18: Combinadores SK

18

Optimización K

Consideremos la expresión \ x -> + 1, cuando es compilada obtenemos la expresión S (K +) (K 1), lo que es poco razonable ya que x no ocurre en el cuerpo de la abstracción.

Un mejor resultado sería la expresión K (+ 1). Esta optimización puede ser obtenida al introducir la siguiente transformación:

S (K p) (K q) => K (p q)

Es trivial mostrar que las dos expresiones son extensionalmente iguales.Cuando K (p q) es aplicada a un argumento su reducción requiere sólo un paso, en vez de los tres necesarios para reducir S (K p) (K q). Entonces:

A x [ e ] = K e sii x no ocurre en e

Nota: Completamente perezoso.

Page 19: Combinadores SK

19

El combinador B

Consideremos la siguiente abstracción: \ x -> - x. Esta expresión compila a S (K -) I, lo que es bastante ineficiente ya que el argumento es pasado a la rama izquierda (K -) que a su vez lo descartará.

Sería conveniente tener una versión de S que sólo pase x a la rama derecha. Llamemos esta versión B, con la siguiente regla de reducción:

B f g x = f (g x)

La correspondiente regla de optimización puede ser formulada entonces así:

S (K p) q => B p q

Optimizando nuestro ejemplo tenemos que S (K -) I => B - I

Page 20: Combinadores SK

20

El combinador B (2)

Notar que la optimización introducida ahorra trabajo en tiempo de compilación (el programa resultante es menor) y en tiempo de ejecución, porque hay menos reducciones que efectuar.

De hecho el ejemplo puede aún ser optimizado un poco más, la expresión (B p I) es equivalente a p. Entonces podemos introducir otra regla de optimización:

B p I => p

lo que permite optimizar nuestro ejemplo de la siguiente forma:

B - I => -

Esta última es una muy buena traducción para la expresión, es equivalente a haber aplicado -reducción.

Page 21: Combinadores SK

21

El combinador C

Así como (B f g x) distribuye a x solamente hacia la rama derecha (g) es también conveniente tener un combinador, llamémosle C, que distribuye x sólo a la rama izquierda (f):

C f g x -> f x g

La regla de optimización para C es la siguiente:

S p (K q) => C p q

A continuación resumimos las nuevas reducciones y reglas de optimización:

B f g x -> f (g x) S (K p) (K q) => K (p q)

C f g x -> f x g S (K p) I => p

S (K p) q => B p q

S p (K q) => C p q

Page 22: Combinadores SK

22

Modificaciones al compilador

Formalizaremos las optimizaciones introduciendo una nueva función Opt, la que optimiza a una expresión combinatoria.

A x [ f ] abstrae x de f

A x [ f1 f2 ] = Opt (S (A x [ f1 ]) (A x [ f2 ])

A x [ x ] = I

A x [ cv ] = K cv

Opt [ e ] optimiza e

Opt [ S (K p) (K q) ] = K (p q)

Opt [ S (K p) I ] = p

Opt [ S (K p) q ] = B p q

Opt [ S p (K q) ] = C p q

Opt [ S p q ] = S p q

Page 23: Combinadores SK

23

Combinadores S´, B´,C´ y B*

Existe un caso más en el que se puede optimizar el código generado por el compilador. Esto ocurre cuando se abstraen varias variables de una expresión.

Reglas de reducción Reglas de transformación

S’ c f g x -> c (f x) (g x) S (B x y) z => S’ x y z

B’ c f g x -> c f (g x) B (c f) g => B’ c f g

C’ c f g x -> c (f x) g C (B c f) g => C’ c f g

B* c f g x -> c (f (g x)) B c (B f g) => B* c f g

Page 24: Combinadores SK

24

El tamaño de traducciones SKComo hemos visto una característica común en todos los

ejemplos es que el programa traducido es mucho más grande que en su correspondiente representación lambda.

Se ha demostrado que el tamaño de una expresión combinatoria puede ser, en el peor caso, proporcional al cuadrado del tamaño de la expresión lambda.

Otra observación a hacer es que el algoritmo de compilación a código SK reinspecciona código que ya ha sido parcialmente compilado. Esto puede ser visto en la regla de compilación:

C [ \ x -> e ] = A x [ C [ e ] ]

Page 25: Combinadores SK

25

Ventajas de SK

i) Un conjunto fijo y pequeño de combinadores puede ser implementado en hardware, evitando así un paso de interpretación.

ii) La instanciación del cuerpo de una abstracción es hecho perezosamente, lo que evita instanciar secciones del grafo que luego serían descartadas.

iii) La técnica es completamente perezosa

iv) La máquina de reducción es relativamente simple de implementar.

Page 26: Combinadores SK

26

Desventajas de SK

i) Pasos de ejecución muy pequeños. Se generan muchos nodos de aplicación intermedios que rápidamente son descartados. Mucho consumo de espacio.

ii) La traducción a combinadores es muy costosa comparada con técnicas de compilación de supercombinadores. Programas muy grandes.