Sei sulla pagina 1di 31

Notas de clase para el curso

Introducción a la Teorı́a de la Computación


I Semestre 2018
Profesor: Rodrigo De Castro K.

Capı́tulo 3
Lenguajes y gramáticas
independientes del contexto

Como se ha visto, los autómatas son dispositivos que procesan cadenas de entrada. En
capı́tulos posteriores consideraremos modelos de autómatas con mayor poder computacio-
nal que el de los modelos AFD, AFN y AFN-λ. En el presente capı́tulo estudiaremos una
noción completamente diferente, aunque relacionada, la de gramática generativa, que es
un mecanismo para generar cadenas a partir de un sı́mbolo inicial.

+ Los autómatas procesan cadenas


+ Las gramáticas generan cadenas

3.1. Gramáticas generativas


Las gramáticas generativas fueron introducidas por Noam Chomsky en 1956 como un
modelo para la descripción de los lenguajes naturales (español, inglés, etc). Chomsky
clasificó las gramáticas en cuatro tipos: 0, 1, 2 y 3. Las gramáticas de tipo 2, también
llamadas gramáticas independientes del contexto, se comenzaron a usar en la década de
los sesenta del siglo XX para presentar la sintaxis de lenguajes de programación y para el
diseño de analizadores sintácticos en compiladores.
Una gramática generativa es una cuádrupla, G = (V, Σ, S, P ) formada por dos alfabetos
disyuntos V (alfabeto de variables o no-terminales) y Σ (alfabeto de terminales), una
variable especial S ∈ V (llamada sı́mbolo inicial ) y un conjunto finito P ⊆ (V ∪ Σ)∗ ×
(V ∪ Σ)∗ de producciones o reglas de re-escritura. Una producción (u, v) ∈ P se denota
por u → v y se lee “u produce v”; u se denomina la cabeza y v el cuerpo de la producción.
Se exige que la cabeza de la producción tenga por lo menos una variable.
El significado de la producción u → v es: la cadena u se puede reemplazar (sobre-
escribir) por la cadena v. Comenzando con el sı́mbolo inicial S y aplicando las producciones
de la gramática, en uno o más pasos, se obtienen cadenas de terminales y/o no-terminales.

86
Introducción a la Teorı́a de la Computación. Capı́tulo 3 87

Aquellas cadenas que sólo tengan terminales conforman lo que se denomina el lenguaje
generado por G.
Las gramáticas se clasifican de acuerdo con el tipo de sus producciones:

Gramáticas de tipo 0. No tienen restricciones. También se llaman gramáticas no-restringidas


o gramáticas con estructura de frase en razón de su origen lingüı́stico.

Gramáticas de tipo 1. Las producciones son de la forma u1 Au2 → v1 vv2 , donde A


es una variable y v 6= λ. También se llaman gramáticas sensibles al contexto o
gramáticas contextuales.

Gramáticas de tipo 2. Las producciones son de la forma A → w donde A es una


variable. También se llaman gramáticas independientes del contexto o gramáticas
no-contextuales.

Gramáticas de tipo 3. Las producciones son de la forma A → a o de la forma A → aB,


donde A y B son variables y a es un sı́mbolo terminal. También se llaman gramáticas
regulares.

Se dice que un lenguaje es de tipo i si es generado por una gramática de tipo i. Esta
clasificación de lenguajes se conoce como la jerarquı́a de Chomsky.

3.2. Gramáticas independientes del contexto


Una gramática independiente del contexto (GIC), también llamada gramática no-contextual
o gramática de tipo 2, es una cuádrupla, G = (V, Σ, S, P ) formada por:

1. Un alfabeto V cuyos elementos se llaman variables o sı́mbolos no-terminales.

2. Un alfabeto Σ cuyos elementos se llaman sı́mbolos terminales. Se exige que los


alfabetos Σ y V sean disyuntos.

3. Una variable especial S ∈ V , llamada variable inicial o sı́mbolo inicial de la gramáti-


ca.

4. Un conjunto finito P ⊆ V × (V ∪ Σ)∗ de producciones o reglas de re-escritura.


Una producción (A, v) ∈ P de G se denota por A → v y se lee “A produce v”.
A es una variable y se denomina la cabeza de la producción; v es una cadena en
(V ∪ Σ)∗ , y se denomina el cuerpo de la producción (formado por concatenaciones
de terminales y/o no-terminales). El significado de una producción A → v es el
siguiente: la variable A se puede reemplazar (o sobre-escribir) por la cadena v.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 88

Notación y definiciones. En ejemplos concretos, las variables se denotan con


letras mayúsculas A, B, C, . . . mientras que los elementos de Σ o sı́mbolos terminales se
denotan con letras minúsculas a, b, c, . . . Si A → v es una producción, entonces en una
cadena como xAy, donde x y y ∈ (V ∪ Σ)∗ , la variable A se puede reemplazar por v para
obtener xvy; esto se denota como

xAy =⇒ xvy.

Se dice que xvy se deriva directamente (o en un paso) de xAy. Si se quiere hacer referencia
a la gramática G, se escribe
G
xAy =⇒ xvy ó xAy =⇒G xvy.

Si u1 , u2 , . . . , un son cadenas en (V ∪ Σ)∗ y hay una sucesión de derivaciones directas


G G G
u1 =⇒ u2 , u2 =⇒ u3 , . . . , un−1 =⇒ un

se dice que un se deriva de u1 y se escribe u1 =⇒ un . La anterior sucesión de derivaciones
directas se representa como

u1 =⇒ u2 =⇒ u3 =⇒ · · · =⇒ un−1 =⇒ un

y se dice que es una derivación o una generación de un a partir de u1 . Para toda cadena
∗ ∗
w se asume que w =⇒ w; por lo tanto, u =⇒ v significa que v se obtiene de u utilizando
+
cero, una o más producciones de la gramática. Análogamente, u =⇒ v significa que v se
obtiene de u utilizando una o más producciones. Nótese que se utilizan flechas simples,
→, para producciones y flechas dobles, =⇒, al aplicar las producciones en derivaciones
concretas.
El lenguaje generado por una gramática G se denota por L(G) y se define como
+
L(G) := {w ∈ Σ∗ : S =⇒ w}.

Es decir, el lenguaje generado por G está formado por las cadenas de terminales que se
pueden derivar (o generar) en varios pasos a partir de la variable inicial S, aplicando en
cada paso una producción. La igualdad L(G) = L es estricta y requiere que se satisfagan
las dos contenencias L(G) ⊆ L y L ⊆ L(G); es decir, toda cadena generada por G debe
estar en L, y toda cadena de L debe ser generada por G.
Un lenguaje L sobre un alfabeto Σ se dice que es un lenguaje independiente del contexto
(LIC) o lenguaje no-contextual si existe una GIC G tal que L(G) = L. Dos GIC G1 y G2
son equivalentes si L(G1 ) = L(G2 ).
La denominación “independiente del contexto” proviene del hecho de que en una deri-
vación cada producción o regla de re-escritura A → v se aplica a la variable A indepen-
dientemente de los caracteres que la rodean, es decir, independientemente del contexto en
el que aparece A.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 89

 
Ejemplo Sea G = (V, Σ, S, P ) una gramática dada por:
 
V = {S, A}
Σ = {a, b}
P = {S → aS, S → bA, S → λ, A → bA, A → b, A → λ}.
La manera más conveniente de presentar una gramática es listando sus producciones y
separando con una barra | las producciones de una misma variable. Se supone siempre que
las letras mayúsculas representan variables y las letras minúsculas representan sı́mbolos
terminales. Ası́ la gramática G del presente ejemplo se puede presentar simplemente como:
(
S → aS | bA | λ
G:
A → bA | b | λ

Se tiene S =⇒ λ. Todas las demás derivaciones en G comienzan ya sea con la producción


S → aS o con S → bA. Por lo tanto, tenemos

S =⇒ aS =⇒ a · · · aS =⇒ a · · · a.

S =⇒ bA =⇒ b · · · bA =⇒ b · · · b.
∗ ∗
S =⇒ aS =⇒ a · · · aS =⇒ a · · · abA =⇒ a · · · ab · · · bA =⇒ a · · · ab · · · b.

Por consiguiente L(G) = a∗ b∗ .


Las siguientes cuatro gramáticas también generan el lenguaje a∗ b∗ y son, por lo tanto,
equivalentes a G:
( (
S → aS | bA | λ S → aS | A
G1 : G2 :
A → bA | λ A → bA | λ
 
S → AB
 S → AB | λ

G3 : A → aA | λ G4 : A → aA | a | λ
 
B → bB | λ B → bB | b | λ
 

Para generar la cadena vacı́a λ con la gramática G3 se requieren tres pasos:

S =⇒ AB =⇒ B =⇒ λ.
 
Ejemplo La gramática
  (
S → aS | aA
G:
A → bA | b
genera el lenguaje a+ b+ . Otra gramática equivalente es:

S → AB

0
G : A → aA | a

B → bB | b

Introducción a la Teorı́a de la Computación. Capı́tulo 3 90

 
Ejemplo La gramática
  (
S → 1A | 0
A → 0A | 1A | λ
genera el lenguaje de los números naturales en numeración binaria. Nótese que la única
cadena que comienza con 0, generable con esta gramática, es la cadena 0.
  ∗ ∗ ∗
Ejemplo Encontrar una GIC que genere el lenguaje L 0 10 10 sobre Σ = {0, 1}, es
 decir, el lenguaje de todas las cadenas con exactamente dos unos.

Solución. (
S → A1A1A
G:
A → 0A | λ
Una gramática equivalente es

S → 0S | 1A

0
G : A → 0A | 1B

B → 0B | λ

Esta última gramática G0 se puede obtener a partir de un autómata que acepte el lenguaje
L, tal como se explicará en la sección 3.3.
  n n
Ejemplo Encontrar una GIC que genere el lenguaje L = {a b : n ≥ 0} sobre Σ =
 {a, b}, el cual no es un lenguaje regular.

Solución.
S → aSb | λ.
 
Ejemplo Encontrar una GIC que genere el lenguaje de todos los palı́ndromes sobre
 Σ = {a, b}, el cual no es lenguaje regular.

Solución.
S → aSa | bSb | a | b | λ.
 
Ejemplo Encontrar una GIC que genere el lenguaje L de todas las cadenas sobre
 Σ = {a, b} que tienen un número par de sı́mbolos.

Solución. Las cadenas de longitud par (aparte de la cadena vacı́a λ) se obtienen concate-
nando los cuatro bloques aa, ab, ba y bb. Por lo tanto, para generar el lenguaje L basta
una sola variable que permita concatenar los cuatro bloques de todas las formas posibles.
Las siguientes tres gramáticas generan el lenguaje L:
n
G1 : S → aaS | abS | baS | bbS | λ
n
G2 : S → Saa | Sab | Sba | Sbb | λ
n
G3 : S → aSa | aSb | bSa | bSb | λ
Introducción a la Teorı́a de la Computación. Capı́tulo 3 91

G1 genera las cadenas de L de izquierda a derecha, G2 las genera de derecha a izquierda


y G3 por simetrı́a izquierda-derecha. Ası́ por ejemplo, la cadena baabbb se genera de la
siguiente manera en las tres gramáticas:
En G1 : S =⇒ baS =⇒ baabS =⇒ baabbbS =⇒ baabbb.
En G2 : S =⇒ Sbb =⇒ Sabbb =⇒ Sbaabbb =⇒ baabbb.
En G3 : S =⇒ bSb =⇒ baSbb =⇒ baaSbbb =⇒ baabbb.
Si se combinan las producciones de G1 con las de G2 no necesariamente se genera el
lenguaje L. Por ejemplo, la gramática G4 ,
n
G4 : S → aaS | Sab | baS | Sbb | λ

genera ciertamente cadenas de longitud par, pero no las genera todas ya que es imposible
generar cadenas como abbabb y aaabba (y muchas otras). Se cumple que L(G4 ) ⊆ L pero
L * L(G4 ) y por ende no se tiene la igualdad L = L(G4 ).
Otra gramática que genera el lenguaje L es:
(
S → AAS | λ
G5 :
A→a|b
 
Ejemplo Encontrar una GIC que genere el lenguaje
 
L = {ak bm cn : m = k + n, k, m, n ≥ 0}
sobre el alfabeto Σ = {a, b, c}.
Solución. Las cadenas de L se pueden escribir como ak bm cn = ak bk+n cn = ak bk bn cn .
Utilizamos la variable A para generar ak bk y la variable B para generar bn cn :

S → AB

G : A → aAb | λ

B → bAc | λ

 
Ejemplo Encontrar una GIC que genere el lenguaje
 
L = {ak bm cn : m > k + n, k, n ≥ 0, m ≥ 1}
sobre el alfabeto Σ = {a, b, c}.
Solución. Para resolver este problema, utilizamos como punto de partida la gramática
G del ejemplo anterior. La condición m > k + n significa que hay estrictamente más bes
que el total k + n; el exceso deseado de bes lo podemos obtener por medio de una nueva
variable C colocada entre A y B. Obtenemos ası́ la gramática G0 ,


 S → ACB

A → aAb | λ
G0 :


 B → bAc | λ
C → bC | b

Introducción a la Teorı́a de la Computación. Capı́tulo 3 92

 
Ejercicios de la sección 3.2
 
À Encontrar GIC que generen los siguientes lenguajes sobre Σ = {a, b}:

(i) a∗ b ∪ a.
(ii) a∗ b ∪ b∗ a.
(iii) (ab ∪ ba)∗ .
(iv) a∗ (ab ∪ b)+ .

Á Encontrar GIC que generen los siguientes lenguajes sobre Σ = {a, b}:

(i) {an+1 b2n+1 : n ≥ 0}.


(ii) {an bn+1 a : n ≥ 1}.
(iii) {an bm an+1 : n ≥ 0, m ≥ 1}.
(iv) {an+1 bm a2n : n, m ≥ 0}.
(v) {am bn : m > n ≥ 0}.
(vi) {am bn : m, n ≥ 0, m 6= n}.
(vii) {am bn : m, n ≥ 0, n > 2m}.
(viii) {am bn : 0 ≤ m ≤ n ≤ 2m}.

 Encontrar GIC que generen los siguientes lenguajes sobre Σ = {a, b, c}:

(i) {ak bm an : k, m, n ≥ 0, n = k + 2m}


(ii) {ak bm an : k, m ≥ 0, n ≥ 1, n > k + 2m}
(iii) {ak bm an : k, m, n ≥ 0, k = m + 2n}
(iv) {ak bm an : m, n ≥ 0, k ≥ 1, k > m + 2n}
(v) {ak bm an : k, m, n ≥ 0, m = 2k + n}
(vi) {ak bm an : k, n ≥ 0, m ≥ 1, m > 2k + n}

à Encontrar GIC que generen los siguientes lenguajes sobre Σ = {a, b, c, d}:

(i) {am b2n cn d2m : m, n ≥ 1}.


(ii) {a2n bn cm d2m : m, n ≥ 1}.

Ä Sea Σ = {0, 1}. Encontrar una GIC que genere el lenguaje de las cadenas que tienen
igual número de ceros que de unos.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 93

3.3. Gramáticas regulares


3.3.1 Definición. Una GIC G = (V, Σ, S, P ) se llama regular si sus producciones son de
la forma (
A → aB, a ∈ Σ, A, B ∈ V.
A→λ A ∈ V.
En la producción A → aB, las variables A y B no necesariamente son distintas.
A partir de un autómata AFD o AFN M se puede obtener una gramática regular G, tal
que L(M ) = L(G), siguiendo el procedimiento esquematizado en el diagrama siguiente.
Los estados de M se convierten en las variables de G; el estado inicial de M pasa a ser
la variable inicial de G. Un arco del estado A al estado B con etiqueta a da lugar a la
producción A → aB, y un estado de aceptación C da lugar a la producción C → λ.

Autómata

Gramática regular
a
A B A → aB

C→λ
C

El procedimiento es completamente reversible y establece una correspondencia directa


entre autómatas y gramáticas regulares. En el Teorema 3.3.2 se demuestra que si M es
un AFD, la gramática regular G obtenida satisface L(M ) = L(G), y en el Teorema 3.3.3
se extiende este resultado a autómatas no-deterministas.
3.3.2 Teorema. Dado un AFD M = (Σ, Q, q0 , F, δ), existe una GIC regular G = (V, Σ, S, P )
tal que L(M ) = L(G).
Demostración. Sea V = Q y S = q0 . Las producciones de G están dadas por
(
q → ap si y sólo si δ(q, a) = p.
q → λ si y sólo si q ∈ F.

Demostraremos primero que para toda w ∈ Σ∗ , w 6= λ y para todo p, q ∈ Q se tiene



(1) Si δ(q, w) = p entonces q =⇒ wp.
La demostración de (1) se hace por inducción sobre w. Si w = a y δ(q, a) = p, entonces
q → ap es una producción de G y obviamente se concluye q =⇒ ap. Para el paso inductivo,
sea δ(q, wa) = p0 . Entonces
p0 = δ(q, wa) = δ(δ(q, w), a) = δ(p, a)
Introducción a la Teorı́a de la Computación. Capı́tulo 3 94


donde δ(q, w) = p. Por hipótesis de inducción q =⇒ wp y como δ(p, a) = p0 , entonces
p =⇒ ap0 . Por lo tanto,

q =⇒ wp =⇒ wap0
que era lo que se querı́a demostrar.
A continuación demostraremos el recı́proco de (1): para toda w ∈ Σ∗ , w 6= λ y para
todo p, q ∈ Q se tiene

(2) Si q =⇒ wp entonces δ(q, w) = p.

La demostración de (2) se hace por inducción sobre la longitud de la derivación q =⇒ wp,

es decir, por el número de pasos o derivaciones directas que hay en q =⇒ wp. Si la
derivación tiene longitud 1, necesariamente q =⇒ ap lo cual significa que δ(q, a) = p. Para

el paso inductivo, supóngase que q =⇒ wp tiene longitud n + 1, w = w0 a y en el último
paso se aplica la producción p0 → ap. Entonces

q =⇒ w0 p0 =⇒ w0 ap = wp.

Por hipótesis de inducción, δ(q, w0 ) = p0 y por consiguiente

δ(q, w) = δ(q, w0 a) = δ(δ(q, w0 ), a) = δ(p0 , a) = p,

que era lo que se querı́a demostrar.


Como consecuencia de (1) y (2) se puede ahora demostrar que

(3) Para toda cadena w ∈ Σ∗ , δ(q0 , w) ∈ F si y sólo si S =⇒G w,
lo cual afirma que L(M ) = L(G). En efecto, si w = λ, δ(q0 , w) ∈ F si y sólo si q0 ∈ F . Por

lo tanto, q0 → λ es una producción de G. Ası́ que S =⇒ λ. Recı́procamente, si S =⇒ λ,
necesariamente S =⇒ λ, q0 ∈ F y δ(q0 , λ) ∈ F .
∗ ∗
Sea ahora w 6= λ. Si δ(q0 , w) = p ∈ F , por (1) se tiene q0 =⇒ w, o sea, S =⇒ w.
∗ ∗
Recı́procamente, si S =⇒G w, entonces q0 =⇒G wp =⇒ w donde p → λ. Utilizando (2),
se tiene δ(q0 , w) = p ∈ F .
3.3.3 Teorema. Dada una GIC regular G = (V, Σ, S, P ), existe un AFN M = (Q, Σ, q0 , F, ∆)
tal que L(M ) = L(G).
Demostración. Se construye M = (Q, Σ, q0 , F, ∆) haciendo Q = V , q0 = S y
(
B ∈ ∆(A, a) para cada producción A → aB.
A∈F si A → λ.

Usando razonamientos similares a los del Teorema 3.3.2, se puede demostrar que

A =⇒G wB si y sólo si B ∈ ∆(A, w), para todo w ∈ Σ∗ , w 6= λ,

de donde L(M ) = L(G).


 
Ejemplo Dado el siguiente AFD M , encontrar una gramática regular G tal que
 L(M ) = L(G).
Introducción a la Teorı́a de la Computación. Capı́tulo 3 95

q0 b q1

a
b b b

q2 q3
a

Solución. Según la construcción mencionada arriba, los estados del autómata M son las
variables de la gramática G. Renombramos los estados de M con las letras mayúsculas
S, A, B y C. Toda transición de M da lugar a una producción en G; los estados de
aceptación A y B inducen las producciones A → λ y B → λ, respectivamente.
a

b
S A


 S → bA | aC

A → aA | bC | λ
a G:
b b b 
 B → bS | aB | λ

C → bA | aB

B a C

Puesto que el autómata M es determinista, para cada cadena aceptada u existe una única
trayectoria etiquetada por los sı́mbolos de u, desde el estado inicial hasta un estado de

aceptación; tal trayectoria corresponde a una única derivación S =⇒ u en la gramática
regular G. Ası́ por ejemplo, la cadena baabaa tiene una única trayectoria de aceptación,
a saber, S, A, A, A, C, B, B, la cual corresponde a una única derivación en G:

S =⇒ bA =⇒ baA =⇒ baaA =⇒ baabC =⇒ baabaB =⇒ baabaaB =⇒ baabaa.


  ∗ ∗ ∗
Ejemplo Para el lenguaje regular 0 10 10 , sobre Σ = {0, 1} (el lenguaje de todas las
 cadenas con exactamente dos unos), vimos en la sección 3.2 una gramática
G que lo genera:
Introducción a la Teorı́a de la Computación. Capı́tulo 3 96

(
S → A1A1A
G:
A → 0A | λ
Esta gramática no es regular, pero por medio del AFD

0 0 0

1 1
S A B

y de la construcción del Teorema 3.3.2 se puede obtener una GIC regular G0 que genere
0∗ 10∗ 10∗ : 
S → 0S | 1A

0
G : A → 0A | 1B

B → 0B | λ

Los teoremas anteriores permiten concluir que la familia de los lenguajes regulares está
estrictamente contenida en la familia de los Lenguajes Independientes del Contexto, tal
como se enuncia en el siguiente corolario.

3.3.4 Corolario. 1. Un lenguaje es regular si y solamente si es generado por una


gramática regular.

2. Todo lenguaje regular es un LIC (pero no viceversa).

Demostración.

1. Se sigue del Teorema 3.3.2, el Teorema 3.3.3 y del Teorema de Kleene.

2. Se sigue de la parte 1. Por otro lado, tenemos muchos ejemplos de lenguajes LIC
que no son regulares, como {an bn : n ≥ 0} y el lenguaje de los palı́ndromes sobre el
alfabeto {a, b}.
 
Ejercicios de la sección 3.3
 
À Encontrar gramáticas regulares que generen los siguientes lenguajes:

(i) ba∗ b ∪ b+ .
(ii) a+ b∗ a.
(iii) a∗ b ∪ b∗ a.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 97

3.4. Árboles sintácticos


Un árbol con raı́z es un tipo muy particular de grafo no-dirigido; tiene un nodo especial,
llamado la raı́z del árbol, la cual se ramifica en nodos, llamados descendientes inmediatos,
cada uno de los cuales puede tener, a su vez, descendientes inmediatos, y ası́ sucesiva-
mente. Un nodo puede tener 0, 1, o más descendientes inmediatos pero tiene un único
antecesor inmediato. El único nodo que no tiene antecesores es la raı́z. Los nodos que
tienen descendientes, excepto la raı́z, se denominan nodos interiores. En la terminologı́a
usualmente utilizada, los descendientes inmediatos de un nodo también se denominan
hijos, y los nodos que no tienen descendientes se denominan hojas. Un árbol queda carac-
terizado por la siguiente propiedad: hay una única trayectoria entre la raı́z y cualquier otro
nodo. Los nodos que aparecen en la única trayectoria entre la raı́z y un nodo determinado
N se denominan los ancestros de N .
 
Ejemplo Dos árboles con raı́z:
 

• •

• • • •

• • • • • • • • • • •

• • •

• • • • • •

• • • • • • • • • • •

• • • • • • • • •

• • • •
Introducción a la Teorı́a de la Computación. Capı́tulo 3 98


3.4.1 Definición. Dada una GIC G = (V, Σ, S, P ), el árbol de una derivación S =⇒ w,
con w ∈ Σ∗ , es un árbol con raı́z y con nodos etiquetados, definido recursivamente de la
siguiente forma:
1. La raı́z está etiquetada con el sı́mbolo inicial S.
2. Si en la derivación se utiliza la producción A → s1 s2 · · · sk , donde si ∈ (V ∪ Σ)∗ , el
nodo A tiene k descendientes inmediatos etiquetados con s1 , s2 ,. . . , sk , escritos de
izquierda a derecha.
De esta manera, los nodos interiores están etiquetados con sı́mbolos no terminales, y las
hojas del árbol están etiquetadas con sı́mbolos terminales o con λ. Si se leen de izquierda

a derecha las hojas del árbol de una derivación de S =⇒ w, se obtiene precisamente la
cadena w, con algunos λ intercalados.
Los árboles de derivaciones se suelen llamar árboles sintácticos.
 
Ejemplo Sea G la gramática:
 

S → ABA | AaB

G : A → aA | a

B → bBa | b

Consideremos la siguiente derivación de la cadena abaaa:


(1) S =⇒ ABA =⇒ AbBaA =⇒ AbBaaA =⇒ AbaaA =⇒ Abaaa =⇒ abaaa.
En cada paso de la derivación, se ha subrayado la variable para la cual se ha utilizado
una producción de la gramática G. El árbol de la derivación (1) es:
S

A• B• •A

• • B• • • •A
a b a a

• •
λ a

Las producciones utilizadas en la derivación (1) se pueden aplicar en diferente orden;


obtenemos, por ejemplo, las siguientes derivaciones:
(2) S =⇒ ABA =⇒ aBA =⇒ aBaA =⇒ aBaa =⇒ abBaaa =⇒ abaaa.
(3) S =⇒ ABA =⇒ aBA =⇒ abBaA =⇒ abaA =⇒ abaaA =⇒ abaaa.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 99

Las derivaciones (1), (2) y (3) tienen todas seis pasos y ellas se aplican exactamente las
mismas producciones pero en diferente orden. Las tres derivaciones tienen todas el mis-
mo árbol, exhibido arriba. Los árboles sintácticos muestran únicamente las producciones
utilizadas, no el orden en que se aplican.
Entre las posibles derivaciones de cadenas se distinguen ciertas derivaciones “estánda-
res”, las llamadas derivaciones a izquierda.
3.4.2 Definición. Una derivación se llama derivación a izquierda (o derivación más a
la izquierda) si en cada paso se aplica una producción a la variable que está más a la
izquierda.
En el ejemplo anterior, la derivación (3) es una derivación a izquierda. En general, una
derivación cualquiera se puede transformar siempre en una única derivación a izquierda
cambiando el orden en que se aplican las producciones, de tal forma que en cada paso
se aplica una producción a la variable que esté más a la izquierda. Además, existe una
correspondencia biyectiva entre derivaciones a izquierda y árboles sintácticos, tal como se
enuncia en la siguiente proposición.
3.4.3 Proposición. Toda derivación a izquierda determina un único árbol sintático.
Recı́procamente, cualquier árbol sintático corresponde a una única derivación a izquierda.
 
Ejemplo Encontrar la única derivación a izquierda determinada por el siguiente árbol
 sintáctico proveniente de cierta gramática G con alfabeto de variables V =
{S, A, B, C} y alfabeto de terminales Σ = {a, b, c}.

S

• A• •B
b

C• • •A • •B
b b

• C• •A •
c λ

• • •
c a a

Solución.

S =⇒ bAB =⇒ bCbAB =⇒ bcbAB =⇒ bcbCAB =⇒ bcbcAB =⇒ bcbcaaB


=⇒ bcbcaabB =⇒ bcbcaabλ.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 100

Las hojas del árbol sintáctico forman la cadena generada bcbcaabλ = bcbcaab.
 
Ejercicios de la sección 3.4
 

À Sea G siguiente gramática:



S −→ aS | AaB

G: A −→ aA | a

B −→ bBbB | b

Encontrar una derivación de la cadena aaaabbbb y hallar el árbol de tal derivación.

Á Sea G la siguiente gramática:




 S → ABC | BaC | aB

A → Aa | a
G:


 B → BAB | bab
C → cC | λ

Encontrar derivaciones a izquierda de las cadenas w1 = abab, w2 = babacc, w3 =


ababababc y hallar los árboles de tales derivaciones.

 Encontrar la única derivación a izquierda determinada por el siguiente árbol sintácti-


co proveniente de cierta gramática G con alfabeto de variables V = {S, A, B, C} y
alfabeto de terminales Σ = {a, b, c}.

S

A• S• •A

• • B• • A• •A
λ b a

• A• C• •
λ a

• •
a c
Introducción a la Teorı́a de la Computación. Capı́tulo 3 101

3.5. Gramáticas ambiguas


3.5.1 Definición. Una GIC G = (V, Σ, S, P ) es ambigua si existe (por lo menos) una
cadena w ∈ Σ∗ para la cual hay dos derivaciones a izquierda diferentes. Según la Proposi-
ción 3.4.3, se puede decir de manera equivalente que una GIC G = (V, Σ, S, P ) es ambigua
si existe una cadena w ∈ Σ∗ con dos árboles sintácticos diferentes.
Como consecuencia de esta definición, se concluye que una GIC G = (V, Σ, S, P ) no es
ambigua si toda cadena w ∈ Σ∗ tiene una única derivación a izquierda. Equivalentemente,
G no es ambigua si toda cadena w ∈ Σ∗ tiene único árbol sintáctico.
 
Ejemplo Considérese el alfabeto de terminales Σ = {0, 1, +, ∗} y la gramática G con
 las siguientes producciones:

S →S+S |S∗S |0|1


Si se interpreta el sı́mbolo + como ‘suma’ y el sı́mbolo ∗ como ‘producto’, G genera
expresiones aritméticas sencillas. La ambigüedad surge porque algunas expresiones se
pueden interpretar ya sea como sumas, o ya sea como productos. Por ejemplo, la cadena
1 + 1 ∗ 0 tiene dos derivaciones a izquierda diferentes:

S =⇒ S + S =⇒ 1 + S =⇒ 1 + S ∗ S =⇒ 1 + 1 ∗ S =⇒ 1 + 1 ∗ 0.
S =⇒ S ∗ S =⇒ S + S ∗ S =⇒ 1 + S ∗ S =⇒ 1 + 1 ∗ S =⇒ 1 + 1 ∗ 0.

La primera derivación genera la cadena 1 + 1 ∗ 0 como una suma y la segunda la genera


como un producto. Los árboles de derivación correspondientes a las anteriores derivaciones
son:
S S
• •

S• • •S S• • •S
+ ∗

• S• • •S S• • •S •
1 ∗ + 0

• • • •
1 0 1 1

En la gramática G la ambigüedad se puede eliminar introduciendo paréntesis:

S → (S + S) | (S ∗ S) | 0 | 1

En tal caso el alfabeto de terminales serı́a Σ = 0, 1, +, ∗, (, ) . Aunque la introducción
de paréntesis elimina la ambigüedad, las expresiones generadas tienen un excesivo número
Introducción a la Teorı́a de la Computación. Capı́tulo 3 102

de paréntesis lo que dificulta el análisis sintáctico (en un compilador, por ejemplo). Lo más
corriente en estas situaciones es utilizar gramáticas ambiguas como G siempre y cuando
se establezca un orden de precedencia para los operadores. Lo usual es establecer que ∗
tenga una mayor orden de precedencia que +, es decir, por convención ∗ actúa antes que
+. Por ejemplo, la expresión 1 ∗ 1 + 0 se interpreta como (1 ∗ 1) + 0 sin necesidad de usar
paréntesis.
La ambigüedad es un asunto delicado porque no existe un algoritmo o procedimiento
general que permita decidir si una GIC dada G es o no ambigua. Por consiguiente, en
cada caso concreto hay que proceder por ensayo y error, recurriendo a la definición de
gramática ambigua, para poder concluir si G es o no ambigua.
 
Ejemplo Demostrar que la siguiente gramática G es ambigua y encontrar una gramáti-
 ca G0 no ambigua equivalente a G, es decir, tal que L(G) = L(G0 ).

(
S → aSA | λ
G:
A → bA | λ
Solución. G es ambigua porque para la cadena aab hay dos derivaciones a izquierda
diferentes:
S =⇒ aSA =⇒ aaSAA =⇒ aaAA =⇒ aaA =⇒ aabA =⇒ aab.
S =⇒ aSA =⇒ aaSAA =⇒ aaAA =⇒ aabAA =⇒ aabA =⇒ aab.
Los árboles sintácticos de estas dos derivaciones son:
S S
• •

• S• •A • S• •A
a a

• S• A• • •A • S• •A •
a b a λ

• • • • • •A
λ λ λ λ b


λ

El lenguaje generado por esta gramática es a+ b∗ ∪ λ. Se puede construir una gramática


no-ambigua que genere el mismo lenguaje:

S → AB | λ

0
G : A → aA | a

B → bB | λ

Introducción a la Teorı́a de la Computación. Capı́tulo 3 103

Para ver que la gramática G0 no es ambigua se puede razonar de la siguiente manera: la


cadena λ se puede generar de manera única con la derivación S =⇒ λ. Una derivación
de una cadena no vacı́a debe comenzar aplicando la producción S → AB; la variable A
genera cadenas de aes de manera única y B genera cadenas de bes también de manera
única. Por consiguiente, toda cadena tiene una única derivación a izquierda.
Como el lenguaje L = a+ b∗ ∪ λ es regular, podemos encontrar otra gramática G00 no
ambigua equivalente a G a partir de un AFD M tal que L(M ) = L.

a b

a b
S A B

G00 es la gramática regular inducida por M , según el procedimiento presentado en la


sección 3.3. Puesto que para cada cadena de L existe una única trayectoria de aceptación
en M , la gramática G00 no es ambigua.

S → aA | λ

00
G : A → aA | bB | λ

B → bB | λ

 
Ejercicios de la sección 3.5
 
Para cada una de las siguientes gramáticas G, demostrar que G es ambigua, hallar L(G)
y encontrar una gramática no-ambigua que genere el mismo lenguaje L(G).

À G : S −→ aSb | aaSb | λ.

Á G : S −→ aSb | abS | λ.

 G : S −→ aaS | aaaS | λ
(
S −→ aaSB | b | λ
à G:
B −→ Bb | λ

 S −→ ABA | b | λ

Ä G : A −→ aA | λ

B −→ bB | λ

 S −→ ASB | AB

Å G : A −→ aA | a

B −→ bB | λ

Introducción a la Teorı́a de la Computación. Capı́tulo 3 104

3.6. Forma Normal de Chomsky


3.6.1. Eliminación de las producciones λ.
3.6.1. Definiciones. Sea G = (V, Σ, S, P ) una GIC.

(i) Una producción de G que tenga la forma A → λ se llama producción λ.



(ii) Una variable A de G se dice que es anulable si A =⇒ λ.

Es decir, A es anulable si se puede transformar en la cadena vacı́a λ utilizando las produc-


ciones de G. El conjunto de todas las variables anulables de G se denota como ANUL, o
sea,

ANUL = {A ∈ V : A =⇒ λ}.
Hay un algoritmo muy sencillo para hallar ANUL, presentado a continuación.

Algoritmo para encontrar las variables anulables de una gramática G

INICIALIZAR:
ANUL := {A ∈ V : A → λ es una producción de G}
REPETIR:
ANUL := ANUL ∪ A ∈ V : ∃ una producción A → w, w ∈ (ANUL)∗


HASTA:
No se añaden nuevas variables a ANUL

El siguiente teorema establece que las producciones λ no son en realidad necesarias. En


otras palabras, las producciones λ se pueden eliminar de cualquier gramática G transfor-
mando adecuadamente G en una gramática G0 equivalente (esto es, sin alterar el lenguaje
generado). La única producción λ que no se puede eliminar es S → λ, en el caso en el que
λ ∈ L(G).

3.6.2 Teorema. Dada una GIC G, se puede construir una GIC G0 equivalente a G sin
producciones λ, excepto (posiblemente) S → λ.

Demostración. Una vez que se haya encontrado el conjunto ANUL de variables anulables,
por medio del algoritmo anterior, las producciones de λ se pueden eliminar (excepto
S → λ) añadiendo nuevas producciones que simulen el efecto de las producciones λ
eliminadas. Más concretamente, por cada producción A → u de G se añaden todas las
producciones de la forma A → v obtenidas suprimiendo de la cadena u una, dos o más
variables anulables presentes, de todas las formas posibles. La gramática G0 ası́ obtenida
es equivalente a la gramática original G, es decir, L(G) = L(G0 ).
 
Ejemplo Eliminar las producciones λ de0 la siguiente gramática G. Más precisamen-
 te, encontrar una gramática G sin producciones λ, excepto (posiblemente)
Introducción a la Teorı́a de la Computación. Capı́tulo 3 105

S → λ, de tal manera que L(G) = L(G0 ).




 S → AB | ACA | ab

A → aAa | B | CD



G: B → bB | bA

C → cC | λ





D → aDc | CC | ABb

Solución. Primero encontramos el conjunto ANUL de todas las variables anulables de G


por medio del mencionado algoritmo. Obtenemos que ANUL = {C, D, A, S}. Al eliminar
de G las producciones λ (la única es C → λ) se obtiene la siguiente gramática equivalente
a G: 

 S → AB | ACA | ab | B | CA | AA | AC | A | C | λ

A → aAa | B | CD | aa | C | D



0
G : B → bB | bA | b

C → cC | c





D → aDc | CC | ABb | ac | C | Bb

3.6.2. Eliminación de las producciones unitarias


3.6.3. Definiciones. Sea G = (V, Σ, S, P ) una GIC.
(i) Una producción de la forma A → B donde A y B son variables, se llama producción
unitaria.
(ii) El conjunto unitario de una variable A (también llamado conjunto cadena de A) se
define de la siguiente manera:

UNIT(A) :=

{X ∈ V : existe una derivación A =⇒ X que usa únicamente producciones unitarias}.
Por definición, A ∈ UNIT(A).
Por medio del siguiente algoritmo sencillo podemos hallar UNIT(A).
Algoritmo para encontrar el conjunto unitario UNIT(A) de una variable A

INICIALIZAR:
UNIT(A):={A}
REPETIR:

UNIT(A):= UNIT(A) ∪ X ∈ V : ∃ una producción Y → X con Y ∈ UNIT(A)
HASTA:
No se añaden nuevas variables UNIT(A)
Introducción a la Teorı́a de la Computación. Capı́tulo 3 106

3.6.4 Teorema. Dada una GIC G, se puede construir una GIC G0 equivalente a G sin
producciones unitarias.

Demostración. La gramática G0 se obtiene eliminando de G todas las producciones uni-


tarias y añadiendo para cada variable A las producciones (originales) de las variables
contenidas en el conjunto unitario UNIT(A).
 
Ejemplo Eliminar las producciones unitarias de la siguiente gramática.
 


 S → AS | AA | BA | λ

A → aA | a
G:


 B → bB | bC | C
C → aA | bA | B | ab

Solución. Aplicando el algoritmo para cada una de las variables de G, se tiene que:

UNIT(S) = {S}.
UNIT(A) = {A}.
UNIT(B) = {B, C}.
UNIT(C) = {C, B}.

Eliminando las producciones unitarias se obtiene una gramática G0 equivalente:




 S → AS | AA | BA | λ

A → aA | a
G0 :


 B → bB | bC | aA | bA | ab
C → aA | bA | ab | bB | bC

 
Ejemplo Eliminar las producciones unitarias de la siguiente gramática.
 


 S → ACA | CA | ADA | A | C | λ

A → aAa | aa | B | C



G: B → cC | D | C

C → bC





D → aA | λ

Solución. Ejecutando el algoritmo para cada una de las variables de G se obtiene:

UNIT(S) = {S, A, C, B, D}.


UNIT(A) = {A, B, C, D}.
UNIT(B) = {B, C, D}.
UNIT(C) = {C}.
UNIT(D) = {D}.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 107

Eliminando las producciones unitarias se obtiene una gramática G0 equivalente:




 S → ACA | CA | ADA | λ | aAa | aa | bC | cC | aA

A → aAa | aa | cC | bC | aA | λ



0
G B → cC | bC | aA | λ

C → bC





D → aA | λ

3.6.3. Forma Normal de Chomsky (FNC)


Una GIC G = (V, Σ, S, P ) está en Forma Normal de Chomsky (FNC) si todas sus produc-
ciones son de la forma: A → BC (donde B y C son variables, no necesariamente distintas)
ó A → a (con a ∈ Σ). Las producciones de la forma A → BC se denominan producciones
binarias, y las de la forma A → a se llaman producciones simples. La única producción λ
permitida en la FNC es S → λ, para el caso especı́fico en el que λ ∈ L(G).

3.6.5 Teorema (Procedimiento de conversión a FNC). Toda GIC G es equivalente a una


gramática en Forma Normal de Chomsky.

Demostración. Podemos transformar G en una gramática en FNC, equivalente a G, me-


diante el siguiente procedimiento:

1. Eliminar las producciones λ (excepto, posiblemente, S → λ).

2. Eliminar las producciones unitarias.

3. Las producciones resultantes (diferentes de S → λ) son de la forma: A → a ó


A → w, donde |w| ≥ 2. Estas últimas se pueden simular con producciones de la
forma A → BC o A → a. Se introduce primero, para cada a ∈ Σ, una variable
nueva Ta cuya única producción es Ta → a. A continuación, se introducen nuevas
variables, con producciones binarias, para simular las producciones deseadas.

Los pasos 1 y 2 del procedimiento no se pueden invertir ya que al eliminar las producciones
λ pueden aparecer nuevas producciones unitarias. La parte 3 del procedimiento anterior
se ilustra en los dos siguientes ejemplos.
 
Ejemplo Simular la producción A → abBaC mediante producciones binarias y simples.
 
Solución. Introducimos las variables Ta y Tb , y las producciones Ta → a y Tb → b. Entonces
A → abBaC se simula con: 
A → Ta Tb BTa C

Ta → a

Tb → b

Introducción a la Teorı́a de la Computación. Capı́tulo 3 108

Ahora introducimos nuevas variables T1 , T2 , T3 y las producciones binarias necesarias.


Las únicas producciones de estas nuevas variables son las mostradas:


 A → Ta T1

T1 → Tb T2





T → BT
2 3


 T3 → Ta C
Ta → a





Tb → b

 
Ejemplo Simular la producción A → BAaCbb mediante producciones binarias y sim-
 ples.

Solución. Introducimos las variables Ta y Tb , y las producciones Ta → a y Ta → b. Entonces


A → BAaCbb se simula con: 
A → BATa CTb Tb

Ta → a

Tb → b

Ahora introducimos nuevas variables T1 , T2 , T3 , T4 y las producciones binarias necesarias.


Las únicas producciones de estas nuevas variables son las mostradas:



 A → BT1
T1 → AT2





T2 → Ta T3



T3 → CT4

T4 → Tb Tb








 Ta → a

T → b
b

En el siguiente ejemplo se ilustra el procedimiento completo para convertir una gramática


dada a la Forma Normal de Chomsky (FNC).
 
Ejemplo Encontrar una GIC en FNC equivalente a la siguiente a la gramática G.
 


 S → AB | aBC | SBS

A → aA | C
G:


 B → bbB | b
C → cC | λ

Solución. El conjunto de variables anulables es ANUL = {C, A}. Al eliminar las produc-
Introducción a la Teorı́a de la Computación. Capı́tulo 3 109

ciones λ de G (la única es C → λ) se obtiene la gramática equivalente G1 :




 S → AB | aBC | SBS | B | aB

A → aA | C | a
G1 :


 B → bbB | b
C → cC | c

A continuación encontramos los conjuntos unitarios de todas las variables:

UNIT(S) = {S, B}.


UNIT(A) = {A, C}.
UNIT(B) = {B}.
UNIT(C) = {C}.

Al eliminar las producciones unitarias obtenemos la gramática equivalente G2 :




 S → AB | aBC | SBS | aB | bbB | b

A → aA | a | cC | c
G2 :


 B → bbB | b
C → cC | c

Luego introducimos las variables nuevas Ta , Tb y Tc , y las producciones Ta → a, Tb → b


y Tc → c con el propósito de que todas las producciones sean unitarias o de la forma
A → w, donde |w| ≥ 2.



 S → AB | Ta BC | SBS | Ta B | Tb Tb B | b
A → Ta A | a | Tc C | c





B → Tb Tb B | b



G3 : C → Tc C | c

Ta → a








 Tb → b

T → c
c

Finalmente, se introducen nuevas variables, con producciones binarias, para simular


Introducción a la Teorı́a de la Computación. Capı́tulo 3 110

las producciones de la forma A → w, donde |w| ≥ 2:



S → AB | Ta T1 | ST2 | Ta B | Tb T3 | b


A → Ta A | TC C | a | c





B → Tb T3 | b





C → Tc C | c





T → BC
1
G4 :


 T2 → BS
T3 → Tb B





Ta → a





Tb → b





Tc → c

En algunas aplicaciones de la FNC es necesario exigir que la variable inicial S no aparezca


en el cuerpo de ninguna producción. Si S aparece en el lado derecho de alguna producción
+
se dice que S es recursiva ya que esto da lugar a derivaciones de la forma S =⇒ uSv,
con u, v ∈ (V ∪ Σ)∗ . El siguiente teorema es un resultado muy sencillo; establece que
cualquier GIC se puede transformar en una GIC equivalente en la cual la variable inicial
no es recursiva.

3.6.6 Teorema. Dada una GIC G = (V, Σ, S, P ) se puede construir una GIC G0 =
(V 0 , Σ, S 0 , P 0 ) equivalente a G de tal manera que el sı́mbolo inicial S 0 de G0 no aparezca
en lado derecho de las producciones de G0 .

Demostración. La nueva gramática G0 tiene una variable más que G, la variable S 0 , que
actúa como la nueva variable inicial. Es decir, V 0 = V ∪ {S 0 }. El conjunto de producciones
P 0 está dado por P 0 = P ∪ {S 0 → S}. Es claro que L(G) = L(G0 ) y el sı́mbolo inicial S 0
no aparece en el cuerpo de las producciones.
Según este resultado, el papel de la variable inicial de la nueva gramática G0 es única-
mente iniciar las derivaciones.
  0
Ejemplo Encontrar una GIC G equivalente a la siguiente gramática G de tal manera
 que la variable inicial de G0 no sea recursiva.


S → ASB | BA

G: A → aA | a

B → bBS | λ

Solución. Según se indicó en la demostración del Teorema 3.6.6, la gramática pedida G0


Introducción a la Teorı́a de la Computación. Capı́tulo 3 111

es  0

 S →S

S → ASB | BA
G0 :


 A → aA | a
B → bBS | λ

Nótese que S sigue siendo recursiva pero ya no es la variable inicial de la gramática.


 
Ejemplo Encontrar una GIC en FNC equivalente a la gramática G del ejemplo anterior,
 de tal manera que su variable inicial no sea recursiva.
Solución. Comenzamos transformando G en G0 , como se hizo en el ejemplo anterior. En
G0 se tiene que ANUL = {B}. Eliminando la producción B → λ obtenemos:
 0

 S →S

S → ASB | AS | BA | A
G1 :


 A → aA | a
B → bBS | bS

Los conjuntos unitarios son: UNIT(S 0 ) = {S 0 , S, A}, UNIT(S) = {S, A}, UNIT(A) =
{A} y UNIT(B) = {B}. Eliminando las producciones unitarias se obtiene la gramática:
 0

 S → ASB | AS | BA | aA | a

S → ASB | AS | BA | aA | a
G2 :


 A → aA | a
B → bBS | bS

Simulando las producciones de G2 con producciones binarias y simples se obtiene:




 S 0 → AT1 | AS | BA | Ta A | a

S → AT1 | AS | BA | Ta A | a





A → Ta A | a





B → T T | T S
b 2 b
G3 :


 Ta → a
Tb → b





T1 → SB





T2 → BS

Introducción a la Teorı́a de la Computación. Capı́tulo 3 112

 
Ejercicios de la sección 3.6
 

À Eliminar las producciones λ de la siguiente gramática G:




 S −→ BCB

A −→ aA | ab



G: B −→ bBa | A | DC

C −→ aCb | D | b





D −→ aB | λ

Á Eliminar las producciones λ de la siguiente gramática G:




 S → EA | SaBb | aEb

A → DaD | bD | BEB



G: B → bB | Ab | λ

D → aEb | ab





E → aA | bB | λ

 Eliminar las producciones unitarias de la siguiente gramática G:



S → Ba | A | λ

G: A → Aa | a

B → bB | S

à Eliminar las producciones unitarias de la siguiente gramática G:



S → BBa | A | B | ab | λ


A → Aa | B | D | aC



G: B → bB | aA | b

C → ABb | A | aB





D → cC | c

Ä Eliminar las producciones unitarias de la siguiente gramática G:




 S → ACA | ab | B | CA | A | C | λ

A → aAa | B | CD | aa | D



G: B → bB | bA | b

C → cC | c





D → ABb | ac | C | Bb
Introducción a la Teorı́a de la Computación. Capı́tulo 3 113

Å Encontrar una gramática en FNC equivalente a la siguiente gramática G:




 S → ABC | BaC | aB

A → Aa | a
G:


 B → BAB | bab
C → cC | c

Æ Encontrar una gramática en FNC equivalente a la siguiente gramática G:




 S → aASb | BAb

A → Aa | a | λ
G:


 B → BAB | bAb
C → cCS | λ

Ç Para la gramática del ejercicio Æ encontrar una GIC equivalente en FNC, de tal
manera que su variable inicial no sea recursiva.

3.7. Propiedades de clausura de los LIC


En la sección 2.12 se vio que los lenguajes regulares son cerrados bajo la unión, la conca-
tenación, la estrella de Kleene y todas las operaciones booleanas (intersección, diferencia
y complemento). Los LIC poseen propiedades de clausura mucho más restringidas: son
cerrados para las operaciones regulares (Teorema 3.7.1) pero, en general, no son cerrados
para intersección, complementos ni diferencias (Teorema 3.7.2).
3.7.1 Teorema. La colección de los lenguajes independientes del contexto es cerrada para
las operaciones regulares (unión, concatenación y estrella de Kleene). Es decir, dadas GIC
G1 = (V1 , Σ, S1 , P1 ) y G2 = (V2 , Σ, S2 , P2 ) tales que L(G1 ) = L1 y L(G2 ) = L2 , se pueden
construir GIC que generen los lenguajes L1 ∪ L2 , L1 L2 y L∗1 , respectivamente.
Demostración. Si pérdida de generalidad, podemos suponer que G1 y G2 no tienen
variables en común (en caso contrario, simplemente cambiamos los nombres de las varia-
bles). Para construir una GIC G que genere L1 ∪ L2 introducimos una variable nueva S,
la variable inicial de G, junto con las producciones S → S1 y S → S2 . Las producciones
de G1 y G2 se mantienen. Concretamente,

G = V1 ∪ V2 ∪ {S}, Σ, S, P1 ∪ P2 ∪ {S → S1 , S → S2 } .
Esquemáticamente, G tiene el siguiente aspecto:
S → S1 | S2
)
S1 → · · ·
.. .. producciones de G1
. .
)
S2 → · · ·
.. .. producciones de G2
. .
Introducción a la Teorı́a de la Computación. Capı́tulo 3 114

Claramente, L(G) = L1 ∪ L2 .
Una GIC G que genere L1 L2 se construye similarmente, añadiendo la producción S →
S1 S2 . Es decir, 
G = V1 ∪ V2 ∪ {S}, Σ, S, P1 ∪ P2 ∪ {S → S1 S2 } .
Esquemáticamente, G es la gramática:

S → S1 S2
)
S1 → · · ·
.. .. producciones de G1
. .
)
S2 → · · ·
.. .. producciones de G2
. .

Claramente, L(G) = L1 L2 .
Para generar L∗1 se define G como

G = V1 ∪ {S}, Σ, S, P1 ∪ {S → S1 S, S → λ} .

Esquemáticamente, G es la gramática:

S → S1 S | λ
)
S1 → · · ·
.. .. producciones de G1
. .
 
Ejemplo Utilizar las construcciones del Teorema 3.7.1 para encontrar una GIC que
 genere el lenguaje L L∗ donde L = ba+ y L = {am bn am : m ≥ 0, n ≥ 1}.
1 2 1 2

Solución. El lenguaje L1 se puede generar con la gramática


(
S1 → bA
A → aA | a

y L2 con (
S2 → aS2 a | bB
B → bB | λ
La siguiente gramática genera L∗2 :

S3 → S2 S3 | λ

S2 → aS2 a | bB

B → bB | λ

Introducción a la Teorı́a de la Computación. Capı́tulo 3 115

Finalmente, el lenguaje L1 L∗2 se puede generar con




 S → S1 S3

S1 → bA





A → aA | a
S3 → S2 S3 | λ


S2 → aS2 a | bB





B → bB | λ.

3.7.2 Teorema. Sean L, L1 y L2 lenguajes independientes del contexto con el mismo


alfabeto de terminales Σ. Entonces

(1) La intersección L1 ∩ L2 no necesariamente es un LIC.

(2) El complemento L no necesariamente es un LIC.

(3) La diferencia L1 − L2 no necesariamente es un LIC.

Demostración.

(1) La intersección de dos LIC puede ser un lenguaje que no es LIC. Considérense, como
ejemplo, los lenguajes

L1 = {am bm cn : m, n ≥ 0},
L2 = {am bn cn : m, n ≥ 0}.

Tanto L1 como L2 son LIC porque son generados por las gramáticas G1 y G2 , respec-
tivamente:
 
S → AB
 S → AB

G1 : A → aAb | λ G2 : A → aA |
 
B → cB | λ B → bBc | λ
 

Pero L1 ∩ L2 = {an bn cn : n ≥ 0} no es un LIC, según se puede demostrar usando el


lema de bombeo (véase la Bibliografı́a).

(2) Razonamos por contradicción: si el complemento de todo LIC fuera un LIC se podrı́a
concluir que la intersección de dos LIC L1 y L2 serı́a un LIC ya que L1 ∩L2 = L1 ∪ L2 .
Esto estarı́a en contradicción con la parte (1) del presente teorema.

(3) Razonamos por contradicción: si la diferencia de dos LIC cualesquiera fuera un LIC
se podrı́a concluir que el complemento de un LIC L serı́a también un LIC ya que
L = Σ∗ − L. Esto estarı́a en contradicción con la parte (2) del presente teorema.
Introducción a la Teorı́a de la Computación. Capı́tulo 3 116

 
Ejercicios de la sección 3.7
 
À Utilizar las construcciones del Teorema 3.7.1 para encontrar GIC que generen los
siguientes lenguajes:

(i) a+ (a ∪ bab)∗ (b∗ ∪ a∗ b).


(ii) (L1 ∪ L2 )L∗3 , donde L1 = ab∗ a, L2 = a ∪ b+ y L3 = {ai bai : i ≥ 0}.
(iii) L1 ∪ L∗2 L3 , donde L1 = ab∗ a, L2 = {ai bj cj di : i, j ≥ 1} y L3 = b+ .

Á Sea G = (V, Σ, S, P ) una gramática que genera al lenguaje L. ¿La gramática G =


V, Σ, S, P ∪ {S → SS, S → λ} genera a L∗ ?


 Demostrar que los LIC son cerrados para la operación de reflexión. Concretamente,
demostrar que si L es un LIC, también lo es el lenguaje LR = {wR : w ∈ L}.

Potrebbero piacerti anche