Definición precisa de categorías sintácticas / dominios sintácticos en sintaxis abstracta

8

He leído las partes introductorias de un par de libros sobre semántica del lenguaje de programación (Gordon, Winskel, Nielson & Nielson, Allison, Stump, Schmidt), y si bien entiendo lo que significan por categorías sintácticas o dominios sintácticos , no entendí No encuentre una definición rigurosa y directa de esos. ¿Existe una definición estándar, tal vez en trabajos anteriores?

josh
fuente

Respuestas:

7

La mayoría de las personas evitan dar descripciones precisas de lo que es una categoría sintáctica, porque si lo hace correctamente con todos los detalles, la relación entre la comprensión y la sofisticación matemática necesaria termina siendo muy, muy baja. El libro de John Reynolds, Teorías de los lenguajes de programación, tiene una de las explicaciones más completas en su capítulo 1, al igual que los Fundamentos prácticos de los lenguajes de programación de Robert Harper .

La intuición que debe tener es que una categoría sintáctica es el conjunto de árboles generados por una gramática libre de contexto. Dada una definición de este tipo para un conjunto de árboles, puede definir funciones en este conjunto utilizando la recursión estructural y probar propiedades sobre ellos mediante la inducción estructural : es decir, analizando las diferentes formas en que se podría construir un árbol.

Por ejemplo, supongamos que tenemos un lenguaje de operaciones aritméticas dado por la siguiente gramática:

e ::= zero | succ(e)| add(e, e)

Luego, podemos definir una función de interpretación evalque toma un término y le da un número entero, por casos, sobre las formas en que podemos construir un término:

eval : Expr -> Int
eval zero     = 0
eval succ(e)  = 1 + eval e  
eval add(e, e') = eval e + eval e'*

Tenga en cuenta que hemos definido completamente esta función al dar una cláusula por cada posible forma en que podríamos haber generado una expresión a partir de la gramática. El hecho de que esta es una definición completa de una función se llama principio de recursión estructural .

También podemos probar las propiedades de esta función mediante el uso de inducción estructural , haciendo un análisis inductivo para cada caso. Por ejemplo, podemos demostrar que para cada e, eval e ≥ 0.

Proof. By structural induction on e.
- Case e = zero:
  By the definition of eval, eval zero = 0. 
  We know 0 ≥ 0 by reflexivity of ≥.    

- Case e = succ(e'):     
  By induction, we know that eval e' ≥ 0 
  So we also know that 1 + eval e' ≥ eval e'.
  By transitivity, 1 + eval e' ≥ 0. 
  But eval succ(e') = 1 + eval e'.
  So eval succ(e') ≥ 0.

- Case e = add(e', e'').
  By induction, we know that eval e' ≥ 0.
  By induction, we know that eval e'' ≥ 0.
  By properties of addition, we know that eval e' + eval e'' ≥ 0.
  By the definition of eval, eval add(e',e'') = eval e' + eval e''.
  So eval add(e',e'') ≥ 0.

El hecho de que considerar solo los casos de cómo podrían formarse las expresiones constituye una prueba se llama principio de inducción estructural .

Ahora, es un hecho que uno puede definir funciones por recursión estructural y probar propiedades por inducción estructural para cualquier gramática. Sin embargo, demostrar esto rigurosamente requiere una cierta cantidad de teoría de categorías; necesita formalizar categorías sintácticas como álgebras iniciales de una determinada clase de functores, y luego demostrar que tales álgebras iniciales siempre existen para esa clase.

Estas son herramientas realmente pesadas para probar un resultado tan "obvio", por lo que recomiendo confiar en su intuición sobre cómo funcionan las definiciones estructurales, y luego solo molestarse con su semántica detallada si decide convertirse en un lógico profesional.

Neel Krishnaswami
fuente
1
Si tan solo pudiéramos utilizar la inducción estructural. Una vez que un idioma tiene ligantes, las cosas se vuelven más complicadas.
Martin Berger
4

Nunca encontré una definición explícita tampoco, pero he inferido lo siguiente.

Según tengo entendido, divide el idioma en dominios sintácticos; con la adición de que los dominios sintácticos deben generarse completamente mediante símbolos únicos diferentes, cuando escriba la gramática. Por lo tanto, un dominio sintáctico es un subconjunto de su idioma, y ​​cada dominio se genera mediante un solo símbolo.

(No dije que debería particionar el lenguaje, porque entonces no se permitiría que un identificador " " estuviera en "expresiones enteras" y "expresiones booleanas", por ejemplo)x

Tenga en cuenta que con esta definición, puede tener diferentes categorías sintácticas al definir la sintaxis abstracta de un lenguaje (es decir, la sintaxis abstracta puede no ser única). Un ejemplo simple: suponga que necesita especificar la sintaxis abstracta para expresiones, tanto enteras como booleanas. Llame a el conjunto de enteros y al conjunto de valores booleanos.B ={T,F}ZB={T,F}

Se podría decir que todas sus expresiones son un dominio sintáctico,

  • Exp contiene todas las expresiones y se asignará mediante una función semántica enZB

o podrías decidir dividirlos:

  • ExpBool contiene expresiones booleanas, que serán asignadas por una función semántica enB
  • ExpInt contiene expresiones enteras, que se asignarán mediante una función semántica enZ

Por lo tanto, hasta donde yo entiendo, los dominios sintácticos exactos que se utilizarán son un problema de diseño (me refiero a una decisión que tome al diseñar la sintaxis abstracta para su idioma). Pero ciertamente son subconjuntos de su idioma, y ​​cada dominio sintáctico debe ser generado por un símbolo diferente.

Arrendajo
fuente