Articulo de referencia

Codificación semántica

Una codificación semántica es una traducción entre lenguajes formales . [ 1 ] Para los programadores, la forma más familiar de codificación es la compilación de un lenguaje de p...

Una codificación semántica es una traducción entre lenguajes formales . [ 1 ] Para los programadores, la forma más familiar de codificación es la compilación de un lenguaje de programación a código máquina o bytecode . La conversión entre formatos de documento también constituye una forma de codificación. La compilación de documentos TeX o LaTeX a PostScript también es un proceso de codificación común. Algunos preprocesadores de alto nivel, como Camlp4 de OCaml , también implican la codificación de un lenguaje de programación a otro.

Formalmente, una codificación de un lenguaje A en un lenguaje B es una correspondencia entre todos los términos de A y B. Si existe una codificación satisfactoria de A en B, se considera que B es al menos tan potente (o al menos tan expresivo ) como A.

Propiedades

Una noción informal de traducción no basta para determinar la expresividad de los idiomas, ya que permite codificaciones triviales como asignar todos los elementos de A al mismo elemento de B. Por lo tanto, es necesario definir qué constituye una codificación "suficientemente buena". Esta definición varía según la aplicación.

Comúnmente, una codificación[]:AB{\displaystyle [\cdot ]:A\longrightarrow B}Se espera que contribuya a preservar varias propiedades.

Conservación de composiciones

solvencia
Para cada operador n-arioopagA{\displaystyle op_{A}}de A, existe un operador n-arioopagB{\displaystyle op_{B}}de B tal que
TA1,TA2,,TAnorte,[opagA(TA1,TA2,,TAnorte)]=opagB([TA1],[TA2],,[TAnorte]){\displaystyle \forall T_{A}^{1},T_{A}^{2},\dots ,T_{A}^{n},[op_{A}(T_{A}^{1},T_{A}^{2},\cdots ,T_{A}^{n})]=op_{B}([T_{A}^{1}],[T_{A}^{2}],\cdots ,[T_{A}^{n}])}
lo completo
Para cada operador n-arioopagA{\displaystyle op_{A}}de A, existe un operador n-arioopagB{\displaystyle op_{B}}de B tal que
TB1,TB2,,TBnorte,TA1,,TAnorte,opagB(TB1,,TBnorte)=[opagA(TA1,TA2,,TAnorte)]{\displaystyle \forall T_{B}^{1},T_{B}^{2},\dots ,T_{B}^{n},\exists T_{A}^{1},\dots ,T_{A}^{n},op_{B}(T_{B}^{1},\cdots ,T_{B}^{N})=[op_{A}(T_{A}^{1},T_{A}^{2},\cdots ,T_{A}^{n})]}

(Nota: hasta donde el autor sabe, este criterio de exhaustividad nunca se utiliza).

La preservación de las composiciones resulta útil en la medida en que garantiza que los componentes puedan examinarse por separado o en conjunto sin alterar ninguna propiedad de interés. En particular, en el caso de las compilaciones, esta integridad garantiza la posibilidad de proceder con la compilación individual de los componentes, mientras que la completitud garantiza la posibilidad de la descompilación.

Conservación de reducciones

Esto presupone la existencia de una noción de reducción tanto en el lenguaje A como en el lenguaje B. Normalmente, en el caso de un lenguaje de programación, la reducción es la relación que modela la ejecución de un programa.

Escribimos{\displaystyle \longrightarrow }para un paso de reducción y{\displaystyle \longrightarrow ^{*}}para cualquier número de pasos de reducción.

solvencia
Para cada términoTA1,TA2{\displaystyle T_{A}^{1},T_{A}^{2}}del idioma A, siTA1TA2{\displaystyle T_{A}^{1}\longrightarrow ^{*}T_{A}^{2}}entonces[TA1][TA2]{\displaystyle [T_{A}^{1}]\longrightarrow ^{*}[T_{A}^{2}]}.
lo completo
Para cada términoTA1{\displaystyle T_{A}^{1}}del idioma A y todos los términosTB2{\displaystyle T_{B}^{2}}del idioma B, si[TA1]TB2{\displaystyle [T_{A}^{1}]\longrightarrow ^{*}T_{B}^{2}}entonces existe algoTA2{\displaystyle T_{A}^{2}}de tal manera queTB2=[TA2]{\displaystyle T_{B}^{2}=[T_{A}^{2}]}.

Esta preservación garantiza que ambos lenguajes se comporten de la misma manera. La solidez garantiza que se conserven todos los comportamientos posibles, mientras que la completitud garantiza que la codificación no añada ningún comportamiento. En particular, en el caso de la compilación de un lenguaje de programación, la solidez y la completitud implican que el programa compilado se comporta de acuerdo con la semántica de alto nivel del lenguaje de programación.

Preservación de la terminación

Esto también presupone la existencia de una noción de reducción tanto en el lenguaje A como en el lenguaje B.

solvencia
para cualquier términoTA{\displaystyle T_{A}}, si todas las reducciones deTA{\displaystyle T_{A}}convergen, entonces todas las reducciones de[TA]{\displaystyle [T_{A}]}converger.
lo completo
para cualquier término[TA]{\displaystyle [T_{A}]}, si todas las reducciones de[TA]{\displaystyle [T_{A}]}convergen, entonces todas las reducciones deTA{\displaystyle T_{A}}converger.

En el caso de la compilación de un lenguaje de programación, la solidez garantiza que la compilación no introduzca errores de terminación, como bucles infinitos o recursiones infinitas. La propiedad de completitud resulta útil cuando se utiliza el lenguaje B para estudiar o probar un programa escrito en el lenguaje A, posiblemente extrayendo partes clave del código: si este estudio o prueba demuestra que el programa termina en B, entonces también termina en A.

Preservación de las observaciones

Esto presupone la existencia de una noción de observación tanto en el lenguaje A como en el lenguaje B. En los lenguajes de programación, los observables típicos son resultados de entradas y salidas, en contraposición a la computación pura. En un lenguaje de descripción como HTML , un observable típico es el resultado de la representación de la página.

solvencia
para cada observableobsA{\displaystyle obs_{A}}en términos de A, existe un observableobsB{\displaystyle obs_{B}}de términos de B tales que para cualquier términoTA{\displaystyle T_{A}}con observableobsA{\displaystyle obs_{A}},[TA]{\displaystyle [T_{A}]}tiene observableobsB{\displaystyle obs_{B}}.
lo completo
para cada observableobsA{\displaystyle obs_{A}}en términos de A, existe un observableobsB{\displaystyle obs_{B}}en términos de B tales que para cualquier término[TA]{\displaystyle [T_{A}]}con observableobsB{\displaystyle obs_{B}},TA{\displaystyle T_{A}}tiene observableobsA{\displaystyle obs_{A}}.

Preservación de simulaciones

Esto presupone la existencia del concepto de simulación tanto en el lenguaje A como en el lenguaje B. En un lenguaje de programación, un programa simula a otro si puede realizar las mismas tareas (observables) y posiblemente algunas más. Las simulaciones se utilizan normalmente para describir optimizaciones en tiempo de compilación.

solvencia
para cada términoTA1,TA2{\displaystyle T_{A}^{1},T_{A}^{2}}, siTA2{\displaystyle T_{A}^{2}}simulaTA1{\displaystyle T_{A}^{1}}entonces[TA2]{\displaystyle [T_{A}^{2}]}simula[TA1]{\displaystyle [T_{A}^{1}]}.
lo completo
para cada términoTA1,TA2{\displaystyle T_{A}^{1},T_{A}^{2}}, si[TA2]{\displaystyle [T_{A}^{2}]}simula[TA1]{\displaystyle [T_{A}^{1}]}entoncesTA2{\displaystyle T_{A}^{2}}simulaTA1{\displaystyle T_{A}^{1}}.

La preservación de simulaciones es una propiedad mucho más fuerte que la preservación de observaciones, que implica. A su vez, es más débil que la propiedad de preservación de bisimulaciones . Como en casos anteriores, la solidez es importante para la compilación, mientras que la completitud es útil para probar o demostrar propiedades.

Preservación de equivalencias

Esto presupone la existencia de una noción de equivalencia tanto en el lenguaje A como en el lenguaje B. Normalmente, esta noción puede ser la de igualdad de datos estructurados o la de programas sintácticamente diferentes pero semánticamente idénticos, como la congruencia estructural o la equivalencia estructural.

solvencia
si dos términosTA1{\displaystyle T_{A}^{1}}yTA2{\displaystyle T_{A}^{2}}son equivalentes en A, entonces[TA1]{\displaystyle [T_{A}^{1}]}y[TA2]{\displaystyle [T_{A}^{2}]}son equivalentes en B.
lo completo
si dos términos[TA1]{\displaystyle [T_{A}^{1}]}y[TA2]{\displaystyle [T_{A}^{2}]}son equivalentes en B, entoncesTA1{\displaystyle T_{A}^{1}}yTA2{\displaystyle T_{A}^{2}}son equivalentes en A.

Preservación de la distribución

Esto presupone la existencia de una noción de distribución tanto en el lenguaje A como en el lenguaje B. Normalmente, para la compilación de programas distribuidos escritos en Acute , JoCaml o E, esto significa la distribución de procesos y datos entre varios ordenadores o CPU.

solvencia
si un términoTA{\displaystyle T_{A}}es la composición de dos agentesTA1 | TA2{\displaystyle T_{A}^{1}~|~T_{A}^{2}}entonces[TA]{\displaystyle [T_{A}]}debe ser la composición de dos agentes[TA1] | [TA2]{\displaystyle [T_{A}^{1}]~|~[T_{A}^{2}]}.
lo completo
si un término[TA]{\displaystyle [T_{A}]}es la composición de dos agentesTB1 | TB2{\displaystyle T_{B}^{1}~|~T_{B}^{2}}entoncesTB{\displaystyle T_{B}}debe ser la composición de dos agentesTA1 | TA2{\displaystyle T_{A}^{1}~|~T_{A}^{2}}de tal manera que[TA1]=TB1{\displaystyle [T_{A}^{1}]=T_{B}^{1}}y[TA2]=TB2{\displaystyle [T_{A}^{2}]=T_{B}^{2}}.

Véase también

Referencias

  1. van Glabbeek, Rob (2018), "Una teoría de las codificaciones y la expresividad (Resumen extendido)" , Lecture Notes in Computer Science , Cham: Springer International Publishing, pp. 183–202 , ISBN  978-3-319-89365-5, consultado el 19 de julio de 2025{{citation}}: CS1 mantenimiento: parámetro de trabajo con ISBN ( enlace )
  • Wiki de transformación de programas