Articulo de referencia

Máquina CEK

Una máquina CEK es una máquina abstracta inventada por Matthias Felleisen y Daniel P. Friedman que implementa la llamada por valor de izquierda a derecha . [ 1 ] Generalmente se...

Una máquina CEK es una máquina abstracta inventada por Matthias Felleisen y Daniel P. Friedman que implementa la llamada por valor de izquierda a derecha . [ 1 ] Generalmente se implementa como un intérprete para lenguajes de programación funcional , pero también puede usarse para implementar lenguajes de programación imperativos simples . Un estado en una máquina CEK incluye una instrucción de control, un entorno y una continuación . La instrucción de control es el término que se está evaluando en ese momento, el entorno es (generalmente) un mapa de nombres de variables a valores, y la continuación almacena otro estado o un caso especial de parada. Es una forma simplificada de otra máquina abstracta llamada máquina SECD . [ 2 ] [ 3 ] [ 4 ]

La máquina CEK se basa en la máquina SECD reemplazando el volcado ( pila de llamadas ) con la continuación más avanzada y colocando los parámetros directamente en el entorno, en lugar de insertarlos primero en la pila de parámetros. Se pueden realizar otras modificaciones que crean toda una familia de máquinas relacionadas. Por ejemplo, la máquina CESK tiene el entorno mapeando las variables a un puntero en el almacenamiento, que es efectivamente un montón. Esto le permite modelar el estado mutable mejor que la máquina CEK ordinaria. La máquina CK no tiene entorno y puede usarse para cálculos simples sin variables. [ 5 ]

Descripción

Se puede crear una máquina CEK para cualquier lenguaje de programación, por lo que el término se usa a menudo de forma vaga. Por ejemplo, se podría crear una máquina CEK para interpretar el cálculo lambda . Su entorno asigna variables a cierres y las continuaciones son una parada, una continuación para evaluar un argumento (ar) o una continuación para evaluar una aplicación después de evaluar una función (ap): [ 4 ] [ 6 ]

Sobre el cálculo lambda sin tipos

En el artículo original [ 7 ] , los autores describen la máquina CEK utilizando semántica operacional de pasos pequeños sobre el cálculo lambda sin tipado:

incógnita,mi,Kϵ,,retirado(mi[incógnita])Kλincógnita.METRO,mi,Kϵ,,retirado((λincógnita.METRO,mi))KMETROnorte,mi,KMETRO,mi,arg(norte,mi)Kϵ,,retirado(F)arg(norte,mi)Knorte,mi,aplicación(F)KF=λincógnita.METROϵ,,retirado(V)aplicación(F)KMETRO,mi[incógnitaV],KF=λincógnita.METRO{\displaystyle {\begin{aligned}\langle x,{\text{E}},{\text{K}}\rangle &\mapsto \langle \epsilon ,\emptyset ,{\text{ret}}(E[x])\gg {\text{K}}\rangle \\\langle \lambda xM,{\text{E}},{\text{K}}\rangle &\mapsto \langle \epsilon ,\emptyset ,{\text{ret}}((\lambda xM,{\text{E}}))\gg {\text{K}}\rangle \\\langle M\,N,{\text{E}},{\text{K}}\rangle &\mapsto \langle M,{\text{E}},{\text{arg}}(N,{\text{E}})\gg {\text{K}}\rangle \\\langle \epsilon ,\emptyset ,{\text{ret}}(F)\gg {\text{arg}}(N,{\text{E}})\gg {\text{K}}\rangle &\mapsto \langle N,{\text{E}},{\text{app}}(F)\gg K\rangle \quad &F=\lambda xM\\\langle \epsilon ,\emptyset ,{\text{ret}}(V)\gg {\text{app}}(F)\gg {\text{K}}\rangle &\mapsto \langle M,{\text{E}}[x\mapsto V],K\rangle \quad &F=\lambda xM\\\end{aligned}}}

dónde{\displaystyle \gg }es una ligadura monádica en las continuaciones,mi[incógnitaV]{\displaystyle {\text{E}}[x\mapsto V]}es un entorno ampliado con un nuevo enlace.

Por ejemplo, el término(λincógnita.incógnita+1)5{\displaystyle (\lambda x.x+1)\,5}Se evalúa siguiendo los siguientes pasos:

(λincógnita.incógnita+1)5,mi,K(λincógnita.incógnita+1),mi,arg(5,mi)Kϵ,,retirado((λincógnita.incógnita+1,mi))arg(5,mi)K5,mi,aplicación((λincógnita.incógnita+1,mi))Kϵ,,retirado(5)aplicación((λincógnita.incógnita+1,mi))Kincógnita+1,mi[incógnita5],Kϵ,,retirado(6)K{\displaystyle {\begin{aligned}&\langle (\lambda x.x+1)\,5,{\text{E}},{\text{K}}\rangle \\\mapsto \quad &\langle (\lambda x.x+1),{\text{E}},{\text{arg}}(5,{\text{E}})\gg {\text{K}}\rangle \\\mapsto \quad &\langle \epsilon ,\emptyset ,{\text{ret}}((\lambda x.x+1,{\text{E}}))\gg {\text{arg}}(5,{\text{E}})\gg {\text{K}}\rangle \\\mapsto \quad &\langle 5,{\text{E}},{\text{app}}((\lambda x.x+1,{\text{E}}))\gg {\text{K}}\rangle \\\mapsto \quad &\langle \epsilon ,\emptyset ,{\text{ret}}(5)\gg {\text{app}}((\lambda x.x+1,{\text{E}}))\gg {\text{K}}\rangle \\\mapsto \quad &\langle x+1,{\text{E}}[x\mapsto 5],K\rangle \\\vdots \\\mapsto \quad &\langle \epsilon ,\emptyset ,{\text{ret}}(6)\gg K\rangle \\\end{aligned}}}

donde el cálculo se extiende a los números y la suma (aunque tanto los números como la suma pueden codificarse completamente en el cálculo lambda).

Representación de componentes

Cada componente de la máquina CEK tiene diversas representaciones. La cadena de control suele ser un término que se está evaluando o, a veces, un número de línea. Por ejemplo, una máquina CEK que evalúa el cálculo lambda usaría una expresión lambda como cadena de control. El entorno es casi siempre un mapa de variables a valores o, en el caso de las máquinas CESK, de variables a direcciones en la memoria. La representación de la continuación varía. A menudo contiene otro entorno, así como un tipo de continuación, por ejemplo, argumento o aplicación . A veces es una pila de llamadas, donde cada marco es el resto del estado, es decir, una instrucción de control y un entorno.

Existen otras máquinas estrechamente vinculadas a la máquina CEK.

Máquina CESK

La máquina CESK es otra máquina estrechamente relacionada con la máquina CEK. El entorno en una máquina CESK asigna variables a punteros en un "almacenamiento" (montículo), de ahí el nombre "CESK". Puede utilizarse para modelar estados mutables, por ejemplo, el cálculo Λσ descrito en el artículo original . Esto la hace mucho más útil para interpretar lenguajes de programación imperativos que funcionales. [ 5 ]

Máquina CS

La máquina CS contiene únicamente una instrucción de control y una memoria. También se describe en el artículo original. En una aplicación, en lugar de colocar variables en un entorno, las sustituye por una dirección en la memoria y coloca el valor de la variable en esa dirección. La continuación no es necesaria porque se evalúa de forma diferida ; no necesita recordar evaluar un argumento. [ 5 ]

Máquina SECD

La máquina SECD fue la máquina en la que se basó la máquina CEK. Tiene una pila, un entorno, una instrucción de control y un volcado. El volcado es una pila de llamadas y se usa en lugar de una continuación. La pila se usa para pasar parámetros a las funciones. La instrucción de control se escribió en notación posfija y la máquina tenía su propio "lenguaje de programación". Una instrucción de cálculo lambda como esta:

(MINNESOTA)

se escribiría así:

N:M:ap

donde ap es una función que aplica dos abstracciones juntas. [ 8 ] [ 9 ]

Orígenes

En la página 196 de "Operadores de control, la máquina SECD y laλ{\displaystyle \lambda }-Cálculo", [ 10 ] y en la página 4 del informe técnico del mismo nombre, [ 7 ] Matthias Felleisen y Daniel P. Friedman escribieron "La máquina [CEK] se deriva del intérprete extendido IV de Reynolds.", refiriéndose al intérprete III de John Reynolds en "Intérpretes definicionales para lenguajes de programación de orden superior". [ 11 ] [ 12 ]

A saber, aquí hay una implementación de la máquina CEK en OCaml , que representa términos lambda con índices de De Bruijn:

término de tipo = IND de int (* índice de Bruijn *) | ABS de plazo | APP de término * término

Los valores son cierres , tal como los inventó Peter Landin :

tipo valor = CLO del término * lista de valorestipo cont = C2 de término * lista de valores * cont | C1 de valor * cont | C0let rec continue ( c : cont ) ( v : value ) : value = match c , v with C2 ( t1 , e , k ), v0 -> eval t1 e ( C1 ( v0 , k )) | C1 ( v0 , k ), v1 -> apply v0 v1 k | C0 , v -> v and eval ( t : term ) ( e : value list ) ( k : cont ) : value = match t with IND n -> continue k ( List . nth e n ) | ABS t' -> continue k ( CLO ( t' , e )) | APP ( t0 , t1 ) -> eval t0 e ( C2 ( t1 , e , k )) y apply ( v0 : valor ) ( v1 : valor ) ( k : cont ) = let ( CLO ( t , e )) = v0 en eval t ( v1 :: e ) klet main ( t : term ) : value = eval t [] C0

Esta implementación está en forma desfuncionalizada , con conty continue como la representación de primer orden de una continuación. Aquí está su contraparte refuncionalizada:

let rec eval ( t : term ) ( e : value list ) ( k : value -> ' a ) : ' a = match t with IND n -> k ( List . nth e n ) | ABS t' -> k ( CLO ( t' , e )) | APP ( t0 , t1 ) -> eval t0 e ( fun v0 -> eval t1 e ( fun v1 -> apply v0 v1 k )) and apply ( v0 : value ) ( v1 : value ) ( k : value -> ' a ) : ' a = let ( CLO ( t , e )) = v0 in eval t ( v1 :: e ) klet main ( t : term ) : value = eval t [] ( fun v -> v )

Esta implementación sigue un estilo de paso de continuaciones de izquierda a derecha , donde el dominio de las respuestas es polimórfico, es decir, se implementa con una variable de tipo . [ 13 ] Esta implementación de paso de continuaciones se mapea de nuevo al estilo directo de la siguiente manera:

let rec eval ( t : term ) ( e : value list ) : value = match t with IND n -> List . nth e n | ABS t' -> CLO ( t' , e ) | APP ( t0 , t1 ) -> let v0 = eval t0 e and v1 = eval t1 e in apply v0 v1 and apply ( v0 : value ) ( v1 : value ) : value = let ( CLO ( t , e )) = v0 in eval t ( v1 :: e )let main ( t : term ) : value = eval t []

Esta implementación de estilo directo también se encuentra en forma desfuncionalizada, o más precisamente en forma convertida a cierre. Este es el resultado de desconvertirla a cierre:

tipo valor = FUN de ( valor -> valor )let rec eval ( t : term ) ( e : value list ) : value = match t with IND n -> List . nth e n | ABS t' -> FUN ( fun v -> eval t' ( v :: e )) | APP ( t0 , t1 ) -> let v0 = eval t0 e and v1 = eval t1 e in apply v0 v1 and apply ( v0 : value ) ( v1 : value ) : value = let ( FUN f ) = v0 in f v1let main ( t : term ) : value = eval t []

La implementación resultante es compositiva . Es el auto-intérprete definicional habitual de Scott-Tarski , donde el dominio de valores es reflexivo ( Scott ) y donde las funciones sintácticas se definen como funciones semánticas y las aplicaciones sintácticas se definen como aplicaciones semánticas ( Tarski ).

Esta derivación imita la deconstrucción racional de Danvy de la máquina SECD de Landin . [ 14 ] La derivación inversa (conversión de cierre, transformación CPS y desfuncionalización) está documentada en el artículo de John Reynolds «Intérpretes definicionales para lenguajes de programación de orden superior», que es el origen de la máquina CEK y posteriormente se identificó como un modelo para transformar evaluadores compositivos en máquinas abstractas y viceversa. [ 11 ] [ 15 ]

Tiempos modernos

La máquina CEK, al igual que la máquina Krivine , no solo se corresponde funcionalmente con un evaluador metacircular (a través de una transformación CPS de llamada por valor de izquierda a derecha), [ 15 ] también se corresponde sintácticamente con elλρ^{\displaystyle \lambda {\widehat {\rho }}}cálculo — un cálculo que utiliza sustitución explícita — con una estrategia de reducción de orden aplicativo de izquierda a derecha, [ 16 ] [ 17 ] y de igual manera para la máquina SECD (a través de una transformación CPS de llamada por valor de derecha a izquierda). [ 18 ]

Referencias

  1. Accattoli, Beniamino; Barenbaum, Pablo; Mazza, Damiano (19 de agosto de 2014), "Destilando máquinas abstractas", Actas de la 19.ª conferencia internacional ACM SIGPLAN sobre programación funcional , ACM, págs. 363–376 , doi : 10.1145/2628136.2628154 , ISBN  9781450328739Se diferencian en cómo se comportan con respecto a las aplicaciones: el CEK implementa la llamada por valor de izquierda a derecha, es decir, primero evalúa la parte de la función, mientras que el LAM da precedencia a los argumentos, realizando una llamada por valor de derecha a izquierda.
  2. Jens Palsberg (28 de agosto de 2009). Semántica y especificación algebraica: ensayos dedicados a Peter D. Mosses con motivo de su 60.º cumpleaños . Springer Science & Business Media. págs. 162–. ISBN  978-3-642-04163-1.
  3. Felleisen, Matthias ; Findler, Robert Bruce ; Flatt, Matthew (10 de julio de 2009). Ingeniería semántica con PLT Redex . MIT Press. págs. 113–. ISBN  978-0-262-25817-3.
  4. 1 2 Thielecke, Hayo (9 de diciembre de 2015). "Implementación de lenguajes funcionales con máquinas abstractas" (PDF) . Archivado del original (PDF) el 17 de julio de 2021. Recuperado el 9 de septiembre de 2020 .
  5. 1 2 3 Felleisen, Matías ; Friedman, Daniel P. (octubre de 1986). "Un cálculo para tareas en idiomas de orden superior" (PDF) .
  6. "Un repaso sobre la máquina CEK" . CMSC 330, verano de 2015. Archivado del original el 21 de enero de 2021. Consultado el 19 de septiembre de 2020 .
  7. 1 2 Felleisen , Matthias; Friedman , Daniel P. (1986). Operadores de control, la máquina SECD y laλ{\displaystyle \lambda }-Cálculo (PDF) (Informe técnico). Departamento de Ciencias de la Computación, Universidad de Indiana. 197.
  8. "La máquina virtual SECD" (PDF) . Archivado del original (PDF) el 17 de julio de 2021.
  9. "secd" . www.cs.bath.ac.uk. Archivado del original el 5 de septiembre de 2019. Consultado el 23 de septiembre de 2020 .
  10. Felleisen, Matthias ; Friedman, Daniel (1986). Operadores de control, la máquina SECD y laλ{\displaystyle \lambda }-Cálculo . Descripción formal de conceptos de programación III, Elsevier Science Publishers BV (North-Holland). págs.193–217.doi:10.1007/978-3-319-14125-1_13. 
  11. 1 2 Reynolds, John C. (1972). "Intérpretes definicionales para lenguajes de programación de orden superior". Actas de la conferencia anual de la ACM sobre - ACM '72 . Vol. 2. Actas de la 25.ª Conferencia Nacional de la ACM. págs. 717–740 . doi : 10.1145/800194.805852 .  
  12. Reynolds, John C. (1998). "Interpretadores definicionales revisados". Higher-Order and Symbolic Computation . 11 (4): 355– 361. doi : 10.1023/A:1010075320153 . S2CID 34126862 . 
  13. Thielecke, Hayo (2004). "Polimorfismo de tipo de respuesta en el paso de continuaciones por nombre". Lenguajes y sistemas de programación . Notas de clase en ciencias de la computación. Vol. 2986. Lenguajes y sistemas de programación, 13.º Simposio Europeo sobre Programación, ESOP 2004, LNCS 2986, Springer. págs. 279–293 . doi : 10.1007/978-3-540-24725-8_20 . ISBN   978-3-540-21313-0.
  14. Danvy , Olivier (2004). Una deconstrucción racional de la máquina SECD de Landin (PDF) . Implementación y aplicación de lenguajes funcionales, 16.º Taller Internacional, IFL 2004, Artículos seleccionados revisados, Lecture Notes in Computer Science 3474, Springer. pp. 52–71 . ISSN 0909-0878 .  
  15. 1 2 Ager, Mads Sig; Biernacki, Dariusz; Danvy, Olivier ; Midtgaard, Jan (2003). "Una correspondencia funcional entre evaluadores y máquinas abstractas" . Serie de informes BRICS . 10 (13). 5.ª Conferencia Internacional ACM SIGPLAN sobre Principios y Práctica de la Programación Declarativa (PPDP'03): 8–19 . doi : 10.7146/brics.v10i13.21783 .
  16. Biernacka, Małgorzata; Danvy, Olivier (2007). "Un marco concreto para máquinas de entorno" . ACM Transactions on Computational Logic . 9 (1): 6. doi : 10.1145/1297658.1297664 .
  17. Rozowski, Wojciech (2021). Derivación formalmente verificada de una máquina CEK ejecutable y terminante a partir del cálculo lambda-p-hat por valor (PDF) (Tesis). Universidad de Southampton.
  18. Danvy, Olivier ; Millikin, Kevin (2008). "Una deconstrucción racional de la máquina SECD de Landin con el operador J". Métodos lógicos en informática . 4 (4) 1112: 1– 67. arXiv : 0811.3231 . doi : 10.2168/LMCS-4(4:12)2008 . S2CID 7926360 . 
Obtenido de " https://en.wikipedia.org/w/index.php?title=CEK_Machine&oldid=1340505274 "