next up previous contents
Siguiente: Forma Normal de Greibach Subir: Lenguajes libres de contexto Anterior: Lenguajes libres de contexto   Índice General


Forma Normal de Chomsky

Sea $G=(\Sigma_N,\Sigma_T,P,\$)$ una gramática con $P\subset\Sigma_N\times(\Sigma_N\cup\Sigma_T)^*$ y $X\in\Sigma_N$ un símbolo no-terminal (o una variable). Podemos clasificar tales símbolos $X$ en tres clases:

variables acesibles:
si existe una derivación desde el símbolo inicial que contiene $X$, es decir, existe $\$\longrightarrow ^*\alpha X\beta$ donde $\alpha,\beta\in\mbox{$\Sigma^*$}$.
variables generativas:
si existe una derivación desde el la variable que produce una sentencia $w$, es decir, existe $X\longrightarrow ^*w$ donde $w\in\Sigma_T^*$.
variables útiles:
si existe una derivación desde el símbolo inicial usando $X$ que produce una sentencia $w$, es decir, existe $\$\longrightarrow ^*\alpha X\beta\longrightarrow ^*w$ donde $\alpha,\beta\in\mbox{$\Sigma^*$}$ y $w\in\Sigma_T^*$.

Una gramática está en forma normal de Chomsky (FNC)

La tercera condición es necesaria para poder derivar $\epsilon $. Si $\$$ aparece a la derecha, primero habrá que sustituir las producciones implicadas adecuadamente como lo vimos en la conversión de una gramática lineal por la derecha a una gramática lineal por la izquierda.

Observamos:

Obviamente cualquier gramática en forma normal de Chomsky es una gramática libre de contexto que se verifica directamente analizando la forma de producciones permitidas.

Pero también es valido la otra dirección: para cualquier lenguaje libre de contexto existe una gramática en forma normal de Chomsky, que genera el mismo lenguaje.

La comprobación de este hecho detallamos con la siguiente construcción donde a partir de una gramática libre de contexto dada, elaboramos una nueva gramática en forma normal de Chomsky.

Sea $L$ un lenguaje libre de contexto y $G=(\Sigma_N,\Sigma_T,P,\$)$ una gramática que genere $L$ (es decir $L=L(G)$).

La construcción sigue 5 pasos (asumimos que $\epsilon\notin L$, eso remediamos al final):

  1. eliminamos las variables inútiles
  2. modificamos las reglas para que no haya mezcla de variables y constantes en las partes derechas de las producciones y para que todas las reglas con constantes tengan la forma $X\longrightarrow \sigma$
  3. sustituimos las reglas cuya longitud de su parte derecha es $>2$
  4. sustituimos las reglas de tipo $X\longrightarrow \epsilon$
  5. sustituimos las reglas de tipo $X\longrightarrow Y$, las reglas unitarias.
Las gramáticas después de cada paso llamamos $G=G_0,G_1,G_2,\dots,G_5=G_{FNC}$ respectivamente.

Usamos la siguiente gramática inicial

\begin{displaymath}G_0=(\{\$,A,B,C,D,E,F\},\{a,b,c\},P_0,\$) \end{displaymath}

donde $P_0$ contenga las siguientes producciones:

\begin{eqnarray*}
\$ &\longrightarrow & bDD\;\vert\;Ca\;\vert\;bc \\
A &\longri...
...;\vert\;EF \\
E &\longrightarrow & Eb\\
F &\longrightarrow & a
\end{eqnarray*}

como ejemplo para realizar todos los pasos.

  1. Sabiendo que una variable es inútil si es no-generativa o inacesible realizamos dos subpasos:
    1. eliminamos primero las variables no-generativas $N$ (y todas las reglas con ellas) llamando a la gramática resultante $G_1^\prime$,
    2. eliminamos después las variables inacesibles $I$ (y todas las reglas con ellas).
    Para ello recorremos en forma estructurada las variables y reglas:
    1. para calcular $N$ empezamos con aquellas variables que producen directamente sentencias (incluyendo $\epsilon $) y seguimos el uso de reglas con dichas variables para producir así sucesivamente sentencias (o en otras palabras: `seguimos las reglas desde el lado derecho hacia el lado izquierdo para obtener así la información sobre las variables').

      Una forma de realizar dicho recorrido es empezar con $N=\Sigma_N$ y borrar del conjunto todas aquellas variables que o bien directamente deriven una sentencia o bien lo hacen indirectamente.

      Se observa que solamente $E$ es un símbolo no-generativo, es decir, $N=\{E\}$, $P_1^\prime$ entonces es:

      \begin{eqnarray*}
\$ &\longrightarrow & bDD\;\vert\;Ca\;\vert\;bc \\
A &\longri...
...\\
D &\longrightarrow & CD\;\vert\;a \\
F &\longrightarrow & a
\end{eqnarray*}

    2. para calcular $I$ empezamos con el símbolo inicial y veremos a cuales de las variables se puede llegar directamente y seguimos el uso de reglas con dichas variables para llegar así sucesivamente a nuevas variables (o en otras palabras: `seguimos las reglas para obtener así la información sobre las variables acesibles'). Dicho algoritmo es una exploración de un grafo de dependencia parecido al algoritmo que vimos para detectar estados no-acesibles en un autómata finito.

      Se observa que solamente $F$ es un símbolo inacesible, es decir, $I=\{F\}$, $P_1$ entonces es:

      \begin{eqnarray*}
\$ &\longrightarrow & bDD\;\vert\;Ca\;\vert\;bc \\
A &\longri...
...tarrow & bD\;\vert\;aBA\\
D &\longrightarrow & CD\;\vert\;a \\
\end{eqnarray*}

    Entonces $G_1$ no contiene símbolos inútiles.

  2. Añadimos para cada símbolo terminal $\sigma$ una regla $W_\sigma$ y sustituimos $\sigma$ en todas las reglas de $P_1$, $P_2$ entonces es:

    \begin{eqnarray*}
\$ &\longrightarrow & W_bDD\;\vert\;CW_a\;\vert\;W_bW_c \\
A ...
...tarrow &a\\
W_b&\longrightarrow &b\\
W_c&\longrightarrow &c\\
\end{eqnarray*}

    Entonces $P_2$ solamente contiene reglas con partes derechas siendo $\epsilon $, un símbolo terminal, o una palabra de variables.

  3. Sustituimos cada regla del tipo $X\longrightarrow Y_1Y_1\dots Y_k$ con $k>2$ por las reglas:

    \begin{eqnarray*}
X&\longrightarrow &Y_1X_1\\
X_1&\longrightarrow &Y_2X_2\\
\v...
...tarrow &Y_{k-2}X_{k-2}\\
X_{k-2}&\longrightarrow &Y_{k-1}Y_k\\
\end{eqnarray*}

    donde las $X_i$ son nuevas variables, $P_3$ entonces es:

    \begin{eqnarray*}
\$ &\longrightarrow & W_b\$_1\;\vert\;CW_a\;\vert\;W_bW_c \\
...
...tarrow &a\\
W_b&\longrightarrow &b\\
W_c&\longrightarrow &c\\
\end{eqnarray*}

    Entonces $P_3$ solamente contiene reglas con partes derechas siendo $\epsilon $, un símbolo terminal, o una palabra de una o dos variables.

  4. Eliminamos las reglas que producen $\epsilon $, ¡ojo! tenemos que distinguir entre variables que solamente producen $\epsilon $ y aquellas que también producen $\epsilon $.

    Entonces, el paso se realiza en 3 partes:

    En el ejemplo tenemos: $E=\{A,B,C_1\}, E_\epsilon=\emptyset$, y por eso $P_4$ es:

    \begin{eqnarray*}
\$ &\longrightarrow & W_b\$_1\;\vert\;CW_a\;\vert\;W_bW_c \\
...
...tarrow &a\\
W_b&\longrightarrow &b\\
W_c&\longrightarrow &c\\
\end{eqnarray*}

  5. Para eliminar las reglas unitarias, es decir, reglas de tipo $X\longrightarrow Y$ procedemos:

    \begin{eqnarray*}
\$ &\longrightarrow & W_b\$_1\;\vert\;CW_a\;\vert\;W_bW_c \\
...
...tarrow &a\\
W_b&\longrightarrow &b\\
W_c&\longrightarrow &c\\
\end{eqnarray*}

    En el ejemplo tenemos:

    \begin{eqnarray*}
U_1&=&\{(A,B),(B,C),(B_1,D),(C,W_a),(C_1,A),(C_1,B),(D,W_a)\}\...
...W_a),(C_1,C)\}\\
U_3&=&\{(A,W_a),(C_1,W_a)\}\\
U_4&=&\emptyset
\end{eqnarray*}

    y por eso $P_5$, el sistema de producciones final, queda en:

    \begin{eqnarray*}
\$ &\longrightarrow & W_b\$_1\;\vert\;CW_a\;\vert\;W_bW_c \\
...
...tarrow &a\\
W_b&\longrightarrow &b\\
W_c&\longrightarrow &c\\
\end{eqnarray*}

Observamos en la construcción:

Si el lenguaje de partida $L$ contiene la palabra vacía ($\epsilon\in L$) entonces se detecta en el pasa 4 que el símbolo inicial pertenece a $E$ (o incluso a $E_\epsilon$), en este caso eliminamos con un nuevo símbolo, por ejemplo $\$^\prime$, la aparencia de $\$$ en los lados derechos y añadimos la regla $\$\longrightarrow \epsilon$. Tal gramática sigue estando en forma normal de Chomsky y genera $L$.

Notas:


next up previous contents
Siguiente: Forma Normal de Greibach Subir: Lenguajes libres de contexto Anterior: Lenguajes libres de contexto   Índice General
© 2006, Dr. Arno Formella, Universidad de Vigo, Departamento de Informática