Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Lucio Torrico
A Javier Guachalla, por mostrarme el camino.
TABLA DE CONTENIDO
PREFACIO
PRIMERA PARTE
SEGUNDA PARTE
Este trabajo es una restructuración de un texto anterior, presenta a las gramáticas formales y
sus autómatas asociados reflejando la elegancia y riqueza de ellos.
Se cubren los lenguajes regulares y los lenguajes libres de contexto con alguna amplitud,
menos ambiciosa es la parte dedicada a los lenguajes sensibles.
Como es imaginable, no se ha podido abarcar todo el espectro de este capítulo de la
informática teórica.
Lucio Torrico
luciotorrico@informatica.edu.bo
PRIMERA PARTE
CAPÍTULO 1. INICIAL
Alfabeto o Vocabulario
Un alfabeto es un conjunto finito, no vacío, de símbolos indivisibles u objetos atómicos.
Ejemplos:
Alfabeto de dígitos decimales T={0,1,2,3,4,5,6,7,8,9}
Alfabeto de las letras L={a,b,…,z,A,…,Z}
Símbolo
Un símbolo es un componente elemental del alfabeto. Por componente elemental
entenderemos cualquier elemento u objeto atómico considerado como indivisible.
En los ejemplos de arriba el 3 o la z son elementos y son los casos más usuales, sin embargo,
también consideraremos como indivisible y como un único elemento, es decir, como un
símbolo de un alfabeto a objetos tales como pares ordenados u otros.
Por ejemplo, aunque no son usuales, no debe extrañarnos encontrar alfabetos así:
T={a1, a2, a3, a4, a5} de cinco símbolos, uno de ellos es a3.
N={(A,B), (A,A), (B,A)} de tres símbolos, uno de ellos es (A,B).
V={cadenaquefungecomosímbolo1, cadenaquefungecomosímbolo2} de dos símbolos, uno de
ellos es cadenaquefungecomosímbolo2.
Ejemplos:
Las siguientes son cadenas sobre el alfabeto T={a,b}
u1 = abab
u2 = bbbb
u3 = abbbaaa
u4 =
1
Por razones estrictamente teóricas, en otros contextos se maneja la noción de cadenas
infinitas, es decir, secuencias infinitas de símbolos de un alfabeto T.
También puede ser útil definir las cadenas como tuplas, por ejemplo u3 = (a,b,b,b,a,a,a)
Lenguaje
Un lenguaje es un conjunto de cadenas definidas sobre un alfabeto.
Al ser un conjunto, un lenguaje puede ser infinito o finito (incluso vacío).
Ejemplos:
Los siguientes son lenguajes sobre T={0,1}
L1 = = {} Denominado lenguaje vacío y denotado a menudo por L
L2 = {} Lenguaje que incluye sólo la cadena vacía, denotado a menudo por L
L3 ={0, 1, 01, 10}
L4 = {, 0, 00, 000, 0000, …}
Longitud:
La longitud de w se denota mediante el símbolo |w| y se define como el número de símbolos
que tiene la cadena: |w|=n
La cadena vacía es una secuencia de 0 símbolos.
Ejemplos:
Si w=0101, |w|= 0101| = 4
Si w=, |w| = | = 0
Igualdad de cadenas:
Se dice que w es igual a z, si tienen la misma longitud y los mismos símbolos en idénticas
posiciones. Se denota mediante w=z. Dado que |w|=n y |z|=m:
w=z si se cumple que m = n y (i: 1 i n: ai= bi )
Si w=, w ~ =w
~
~ =w
También, la inversa de la inversa de una cadena es la cadena original: w
Ejemplos:
~ = 1010
Si w=0101, w
2
~ = 111
Si w=111, w
~ = 00111
Si w=11100, w
Concatenación de cadenas:
La concatenación de w con z es la cadena que se obtiene al añadir a la derecha de la cadena w
la cadena z, y se denota por wz (o w·z, aunque a menudo el punto se omite). Es decir, consiste
de todos los símbolos de w seguidos por los símbolos de z.
wz =a1a2…anb1b2…bm
Propiedades de la concatenación:
1) wzes una cadena sobre T
2 ww=w (es el neutro en la concatenación)
3) |wz| |w| + |z|
4) uwz = (uw)z = u(wz)
5) En general no es conmutativa, es decir, comúnmente wz zw
Ejemplos:
Si w = 0101 y z=1111
wz = 01011111
zw = 11110101
zz = 11111111
Ejemplos:
Si w = 0101 y z=1111
z3 = z2z = z1zz = z0zzz = zzz = zzz = 111111111111
w4 = w3w = w2ww = w1www = w0wwww = wwww = wwww = 0101010101010101
|w4| = 4|w| = 16
Prefijo:
Sean u, w y z tres cadenas sobre el alfabeto T.
Se dice que la cadena z es prefijo de w, si para alguna cadena u se obtiene w = zu.
La cadena vacía es prefijo de cualquier palabra.
3
Toda palabra puede considerarse prefijo de sí misma.
El prefijo z de la cadena w se denomina prefijo propio si z w.
Sufijo:
Sean u, w y z tres cadenas sobre el alfabeto T
Se dice que la cadena z es sufijo de w, si para alguna cadena u se obtiene w = uz.
La cadena vacía es sufijo de cualquier palabra.
Toda palabra puede considerarse sufijo de sí misma.
El sufijo z de la cadena w se denomina sufijo propio si z w.
Subcadena:
Sean u, v, w y z cuatro cadenas sobre el alfabeto T.
Una cadena z es una subcadena de otra cadena w si existen la cadenas u y v para las cuales,
w=uzv. En este caso z también recibe el nombre de infijo.
Ejemplos:
Si w=abbaab, Nb(w)=3
Si w=aaa, Nb(w)=0
Sean L1, L2 y L3 tres lenguajes sobre sus respectivos alfabetos, digamos T1, T2 y T3. A menudo
se consideran idénticos los alfabetos, lo que puede hacerse con T = T1 T2 T3.
Unión:
L1 L2 = { u / (u L1 ) ó (u L2 ) }
Intersección:
L1 L2 = { u / (u L1 ) y (u L2 ) }
Concatenación:
L1·L2 = { uv / ( u L1 ) y ( v L2 ) }
(a menudo el punto que denota la operación se omite)
4
Propiedades de la concatenación:
1) L1·=·L1=
2) (L1·L2)·L3 = L1·(L2·L3) asociatividad
3) En general no es conmutativa, es decir, comúnmente L1·L2 L2·L1
4) L1·( L2 L3) = L1·L2 L1·L3 distributividad con respecto a la unión
5) No es distributiva con respecto a la intersección [L1·( L2L3) L1·L2 L1·L3]
Ejemplo:
={,1}·({}{1}) ({,1}·{})({1}·{,1})={1}
Inverso:
~
L1 (ó L1R) denota el inverso de L1
~
L1R = L1 = { u~ / uL1 }
Potencia:
L10= {
L11= L1
L12= L1·L1
L1k= L1k-1.L1
Ejemplos:
Para T={0,1}
T0 ={
T1={0,1
T2={00,01,10,11
T3={000,001,010,011,100,101,110,111}
…
Luego
T*=T0 T1 T2 T3 ... = {0,1,00,01,10,11,000,001,010,011,100,101,110,111,…}
Para T={a,b}
T*={ todas las cadenas que se pueden formar con los símbolos a ó b
en cualquier orden y de cualquier longitud}
={ a, b, aa, ab, ba, bb, aaa, ... }
5
Para T={a}
T*={ a, aa, aaa, ... }
También podemos referirnos a este mismo lenguaje así: {a}*
Para T={b,c,d}
T*={ b, c, d, bb, bc, bd, cb, cc, cd, db, dc, dd, bbb, ... }
También podemos referirnos a este mismo lenguaje así: {b,c,d}*
Diferencia:
Sean L1 y L2 definidos sobre T, L1 T* y L2 T*, es decir, se toma a T* como conjunto
universo.
L1 - L2 = { uT* / uL1 y uL2 }
Complemento:
L1 = { uT* / uL1 } = T* - L1
En este caso se toma a T* como conjunto universo. También se denota por (L1)c.
6
CAPÍTULO 2. GRAMÁTICAS REGULARES
T1={a, b,c}
T2={a}
T3={1,2,3}
T4={1,a,2,b,3}
Nótese que -por convención- generalmente utilizaremos minúsculas o dígitos para los
elementos del alfabeto de Terminales y mayúsculas para los elementos del alfabeto de No
Terminales.
Las Gramáticas Regulares son de dos tipos: Gramáticas Regulares Lineales Derechas y
Gramáticas Regulares Lineales Izquierdas.
Cuando se habla de Gramáticas Regulares alguna literatura sólo hace mención de las
Gramáticas Regulares Lineales Derechas, y en varios casos confunden estos términos, es
decir, hablan de Gramáticas Regulares Lineales Derechas como si fueran las únicas
Gramáticas Regulares.
En estricto rigor es mejor conservar "el apellido", pues –como dijimos- existen Gramáticas
Regulares Lineales Izquierdas y Lineales Derechas.
7
Al segundo elemento lo denominaremos parte derecha de la producción y puede ser de dos
tipos: bien un símbolo Terminal; o bien un símbolo Terminal seguido de un símbolo No
Terminal, T o (T·N).
En vez de un par ordenado, es muy común representar una producción separando las partes
derecha e izquierda por un símbolo de flecha así: --> .
Ejemplo:
La siguiente es una Gramática Regular Lineal Derecha (GRLD) G:
G=(N, T, P, S)
N={S}
T={a,b}
P={ (S,aS), (S,b) }
Como dijimos es usual describir el conjunto de producciones así: P={ S --> aS, S --> b }
Más frecuente aún es describir P a manera de un listado como a continuación mostramos.
P:
S --> aS
S --> b
Nosotros daremos las producciones en forma de listado a menudo.
La parte izquierda es un símbolo No Terminal que generalmente es una mayúscula.
La parte derecha es un símbolo Terminal, generalmente una minúscula o un dígito, que puede
estar solo o seguido de un símbolo No Terminal - generalmente una mayúscula-.
Pueden existir una, dos, tres, etc. producciones, siempre que sea un número finito.
Más ejemplos:
La siguiente es una Gramática Regular Lineal Derecha (GRLD) G:
G=(N, T, P, S)
N={S,X,Y}
T={a,b,c}
P:
S --> aX
X --> bY
Y --> c
8
El siguiente es un mal ejemplo de Gramática Regular Lineal Derecha (GRLD) G:
G=(N, T, P, S)
N={Y,X}
T={a,b}
P:
S --> aS
X --> Ya
aY --> b
a --> b
S --> a
Nótese que S no está en N.
Nótese que la segunda producción no obedece el formato indicado en lo que concierne a la
parte derecha (Terminal solo, ó Terminal seguido de No Terminal), en este caso está al revés.
Nótese que la tercera producción no obedece el formato indicado en lo que concierne a la
parte izquierda (sólo un No Terminal), en este caso tiene dos símbolos.
Nótese que la cuarta producción no obedece el formato indicado en lo que concierne a la parte
izquierda (sólo un No Terminal), en este caso tiene un Terminal.
Una sola de estas observaciones (que no siguen la definición) hace que el ejemplo no sea una
GRLD. Más aún todas juntas.
9
Es común agrupar varias producciones que tienen la misma parte izquierda separando las
partes derechas con una barra. De este modo el conjunto de producciones del último ejemplo
puede presentarse también como mostramos en seguida.
P:
S --> 1S | 2S | 3S | 4S | 5S | 6S | 7S | 8S | 9S | 0S
S --> 0 | 2 | 4 | 6 | 8
Ejemplos:
Sea la GRLD G=(N, T, P, S)
N={S,X,Y}
T={a,b,c}
P:
S --> aX
X --> bY
X --> bX
Y --> c
En los siguientes casos se da un paso de derivación de la cadena u hacia v, es lo mismo -y es
usual- decir que v deriva de u en un paso de derivación:
10
4) Sba => aXba pues
u = Sba v = aXba
en este caso w = z = ba y S --> aX P (es la primera producción)
Nótese que cuando la cadena vacía no está sola, simplemente no la escribimos.
5) Y => c pues
u=Y v=c
en este caso w = z = y Y --> c P (es la cuarta producción)
En la misma GRLD G es evidente que aXa => abXa => abbXa => abbbXa => abbbbXa
donde se ha usado varias veces la tercera producción, esto mismo puede escribirse/resumirse
así aXa =>* abbbbXa, lo que indica que abbbbXa deriva de aXa.
Una forma más amigable de mostrar una derivación paso a paso, por ejemplo de S =>* abc, es
así:
Como convención nótese que usamos doble flecha => (con o sin asterisco) en las
derivaciones, y que utilizamos flecha simple --> en las producciones.
Nos permitiremos escribir que u =>* u para cualquier cadena u.
11
Ejemplo:
Sea la GRLD G=({S,X,Y}, {a,b,c}, P, S)
Nótese la manera en que se presentan N y T, forma también válida.
P:
S --> aX
X --> bY
X --> bX
Y --> c
Con dicha GRLD podemos escribir lo siguiente:
S => aX utilizando la primera producción
=> abX utilizando la tercera producción
=> abbX utilizando la tercera producción
=> abbbX utilizando la tercera producción
=> abbbbY utilizando la segunda producción
=> abbbbc utilizando la cuarta producción
ó lo que es lo mismo S =>* abbbbc
Y también
S => aX utilizando la primera producción
=> abY utilizando la segunda producción
ó lo que es lo mismo S =>* abY
En el primer caso decimos que abbbbc deriva de S; y en el segundo que abY deriva de S.
Una cadena que pueda formarse con los símbolos de (N T), es generable -o se puede
generar- en la GRLD G (a esta cadena suele denominarse forma sentencial) si dicha cadena
deriva de S. Es obvio que una derivación debe respetar la definición, salvo ello hacemos notar
que no hay ni un orden ni un límite en el que se utilice cada una de las producciones.
Hemos llegado a uno de los problemas centrales de las GRLD’s: dada una cadena decir si la
misma deriva o no deriva del símbolo raíz S, es decir, si es una forma sentencial.
Con la GRLD que estamos viendo, la cadena abY si se puede generar en G pues S =>* abY, y
el ejemplo de arriba muestra cómo sería esta derivación paso a paso.
En cambio la cadena aY no se puede generar en G ¡Intente escribir una derivación paso a paso
que comience en S y termine en aY! simplemente es imposible.
Por ahora, para indicar que una cadena sí se puede generar en una GRLD basta la derivación
paso a paso, misma que puede seguirse en detalle para ver si las producciones se han utilizado
correctamente. Sin embargo, para indicar que una cadena no se puede generar en una GRLD
sólo tenemos como ayuda el trabajo mental que podamos hacer con las producciones, más
adelante buscaremos otros recursos.
12
L(G) lenguaje generado por una GRLD
El lenguaje generado por una GRLD G denotado por L(G) se define así:
L(G) = { conjunto de todas las cadenas de sólo Terminales que se pueden generar en G }
Anotaremos exactamente lo mismo de manera formal así:
L(G) = { cadenas v de sólo Terminales / S =>* v } = { v T* / S =>* v }
Ejemplo:
Con la última GRLD G, es claro que abbbbc L(G) pues ya mostramos con todo detalle que
S =>* abbbbc.
Es también posible evidenciar, por inspección de las producciones, que bbb L(G) pues toda
cadena generable en la GRLD debe empezar su derivación utilizando la primera producción
–las otras producciones no tienen a S como parte izquierda-, sin embargo, esta primera
producción convierte S en aX, de manera que las cadenas generables tendrán una a como
primer símbolo Terminal condición que no cumple bbb.
Ya dijimos que, para mostrar que una cadena no se puede generar en una GRLD sólo tenemos
como ayuda la –a veces no tan– simple inspección de las producciones. Cuando la GRLD
tiene pocos Terminales y No Terminales y cuando el número de sus producciones es menor,
este análisis tiende a simplificarse, empero, cuando esto no es cierto, hacen falta recursos
teóricos adicionales y una alta dosis de práctica.
Subrayamos el hecho de que la definición de L(G) dice todas: no dice casi todas, ni algunas.
Dice todas las cadenas de Terminales que se puedan derivar de S. Es claro que ello no incluye
a las cadenas que no se puedan derivar de S.
Ejemplos de L(G):
Sea la GRLD G=({S,X}, {a,b}, P, S)
P:
S --> aX
X --> a
L(G) = {aa} Únicamente la cadena "aa" es de sólo Terminales y derivable desde S
13
Sea la GRLD G=({S,X,Y}, {a,b}, P, S)
P:
S --> aX
X --> bS
L(G) = { } No hay siquiera una cadena de sólo Terminales que se pueda derivar de S
Este ejemplo nos muestra la necesidad de tener una forma de describir los lenguajes cuando
son conjuntos infinitos (o finitos muy grandes). Utilizaremos para ello y de manera libre las
operaciones y notaciones generalmente utilizadas con cadenas y/o lenguajes: la inversa,
concatenaciones, el uso de los paréntesis, potencias de cadenas, longitudes, etc.
Así para este caso tenemos L(G) = {ak / k > 0 } pues
L(G) = {ak / k > 0 } = {a1, a2, a3, ...} = {a, aa, aaa, ...}
14
Sea la GRLD G=({S,X,Y}, {a,b,c}, P, S)
P:
S --> aX
X --> bS
X --> bY
Y --> c
Veamos algunas derivaciones para visualizar el comportamiento de esta GRLD.
i) S=>aX=>abY=>abc
ii) S=>aX=>abS=>abaX=>ababY=>ababc
iii) S=>aX=>abS=>abaX=>ababS=>ababaX=>abababY=>abababc
Esto nos sugiere L(G)={(ab)kc / k > 0}
15
Dado un lenguaje escribir las producciones
Un aspecto complementario consiste en escribir la GRLD G cuando nos dan un conjunto dado
de cadenas de sólo Terminales, es decir un lenguaje propuesto que denotaremos por L.
Ejemplos:
Construya una GRLD G para el lenguaje L={ akbi / k > 0, i > 0 }
Podemos escribir la siguiente GRLD –sólo incluimos las producciones-:
P:
S --> aS
S --> aB
B --> bB
B --> b
16
Es un error frecuente no percibir que hay una diferencia fuerte entre una cadena derivable a
partir de otra cadena y una cadena en L(G), en este último caso se exige que la derivación
empiece en S. Las cadenas en L(G) son cadenas de sólo terminales cuya derivación comienza
en S (no en X, no en bS, no en SS, sino en S sola).
Por ejemplo cuando con alguna GRLD indicamos que bababb está en L(G) pues
X=>bS=>baX=>babS=>babaX=>bababS=>bababb en esa gramática, ello no es correcto pues
esta argumentación incluye una derivación que no comienza en S.
Igual de errado sería indicar que S=>*abb porque sabemos que aX=>abS =>abb.
Otro error común es esperar que las gramáticas se comporten sólo como quisiéramos,
olvidando otras posibles derivaciones. Por ejemplo, cuando se desea escribir una GRLD G
que genere L(G)={(ab) k / k>0}, hay quienes presentan falsas soluciones de este tipo, sólo
incluimos P:
S --> aS
S --> bS
S --> b
Bajo el siguiente razonamiento: esta derivación es posible S=>aS=>ab (por 1 y luego3);
también S=>aS=>abS=>abaS=>abab (por 1, 2, 1 y 3); y también S=>*ababab, S=>*abababab;
etc., luego L(G)= {(ab) k / k>0}.
Todas estas derivaciones son correctas, pero –y aquí está lo errado del razonamiento- no son
las únicas posibles. En esta GRLD también se puede derivar S=>*bbb, S=>*bab, etc.
En estricto rigor para este caso {(ab) k / k>0} ⊂ L(G).
Y, con más precisión, suponiendo T={a,b}: L(G) = {a,b}*·{b} = {ub / u T*}.
El error de esperar que las gramáticas se comporten sólo como quisiéramos o sólo como
vemos muy superficialmente es usual, presentaremos más casos.
Construya una GRLD G que genere L={ oruro }
P erróneo:
S --> oX
X --> rY
Y --> uX
Y --> o genera oro, orururo, etc.
Segundo P erróneo:
S --> oS
S --> rU
U --> uR
R --> rO
O --> o genera ruro, oooooooooruro, ooooruro, etc.
Recordemos que G debe generar oruro y sólo oruro.
17
Construya una GRLD G que genere L={aub / u {a,b}*}
P erróneo:
S --> aX
X --> aY
Y --> bX
X --> bY
Y --> b no genera abab (que está en L)
Otro P erróneo:
S --> aS
S --> bS
S --> a genera a, b, bba, etc.
S --> b
Ejemplos:
Sea la siguiente Gramática Regular Lineal Izquierda G=({S,X,Y}, {a,b,c}, P, S)
P:
S --> Xc
X --> Yb
Y --> a
18
Todas las otras ideas que existen para GRLD’s se aplican a GRLI’s: derivación, L(G), dado
un lenguaje escribir las producciones, etc.
Es interesante cómo las GRLI’s generan los símbolos de derecha a izquierda, al revés que las
GRLD’s.
Una gramática regular o bien es una GRLI o bien es una GRLD, no puede ser ambas cosas a
la vez. Por ejemplo el siguiente conjunto de producciones P:
S --> Sa
S --> aS
S --> Xa
S --> aY
Y --> a no corresponde ni a una GRLI ni a una GRLD. Por ahora no tiene sentido,
X --> b aunque más adelante diremos que es una gramática libre de contexto.
19
Sea la GRLI G=({S,X,Y}, {a,b}, P, S)
P:
S --> Sb | Xb
X --> Xa | a
L(G)={ akbi / k > 0, i > 0 }
20
Si se nos pide escribir una GRLD G que genere cadenas en {a,b}* de longitud par y que
terminen en a, es decir, G debe ser tal que L(G)={ua / u {a,b}* y |u|=2i+1 i }.
Una solución es la que sigue, sólo escribimos P:
S --> aA | bA
A --> aB | bB | a
B --> aA | B--> bA
Si se nos pide escribir una GRLD G que genere cadenas en {0,1,...,8,9}* que interpretadas
como números naturales denoten números divisibles por 3.
Una solución es la que sigue, sólo escribimos P:
S --> 0S
S --> 1U U --> 0U D --> 0D
S --> 2D U --> 1D D --> 1S
S --> 3S U --> 2S D --> 2U
S --> 4U U --> 3U D --> 3D
S --> 5D U --> 4D D --> 4S
S --> 6S U --> 5S D --> 5U
S --> 7U U --> 6U D --> 6D
S --> 8D U --> 7D D --> 7S
S --> 9S U --> 8S D --> 8U
S --> 0 U --> 9U D --> 9D
S --> 3 U --> 2 D --> 1
S --> 6 U --> 5 D --> 4
S --> 9 U --> 8 D --> 7
Si se nos pide escribir una GRLD G que genere cadenas en {0,1,...,8,9}* que interpretadas
como números naturales denoten números impares.
Una solución es la que sigue, sólo escribimos P:
S --> 1S | 2S | 3S | 4S | 5S | 6S | 7S | 8S | 9S | 0S
S --> 1 | 3 | 5 | 7 | 9
Si se nos pide escribir una GRLD G que genere cadenas en {0,1,...,8,9}* que interpretadas
como números naturales denoten números divisibles por 6.
Una solución (que argumentamos más adelante) es la que sigue, sólo escribimos P:
S --> 0S | 1X | 2Y | 3S | 4X | 5Y | 6S | 7X | 8Y | 9S | 0 | 6
X --> 0X | 1Y | 2S | 3X | 4Y | 5S | 6X | 7Y | 8S | 9X | 2 | 8
Y --> 0Y | 1S | 2X | 3Y | 4S | 5X | 6Y | 7S | 8X | 9Y | 4
21
NOTACIÓN, CONVENCIONES Y TOMA DE POSICIÓN
Ya hicimos notar que, según sea la literatura que se revise, existen varias diferencias de
notación. Es típico por ejemplo que muchos textos denoten a la cadena vacía con la letra
griega lambda (), mientras que otros la denotan con la letra griega épsilon (), e incluso con
un cero (0); otros se refieren al alfabeto T con el símbolo , o con VT para el alfabeto de
Terminales y VN para el de No Terminales; en algunos lugares utilizan R para el símbolo raíz;
otros prefieren no hacer diferencia de notación entre --> y =>; etcétera.
Eso no debiera ser un problema, basta establecer un convenio y trabajar con él.
Se sobreentiende que si leemos un documento con otra notación debiéramos hacer un breve
ejercicio mental -si fuera necesario- para traducir dicho documento a “nuestra” notación.
Hay asuntos más complejos que van más allá de la simple notación, se trata de la división que
existe entre los autores acerca de cuestiones, no de matiz, sino de fondo.
Por ejemplo está el caso teórico de si P (el conjunto de producciones) puede ser vacío o no,
algunos teóricos aceptan que P pueda tener cero producciones; y otros exigen que P sea no
vacío; en el tratamiento de autómatas finitos –capítulo que veremos más adelante- ciertos
autores aceptan F vacío y otros exigen F no vacío; y como estas hay otras divergencias de
fondo.
Hay una que es central: algunos autores aceptan una GRLD G=({S}, {b}, P, S) así:
P:
S --> bS
S -->
Para indicar una GRLD G que genere L(G)={ bk / k 0 } Se sabe aquí que b0 =
Es decir que la parte derecha de una producción no sólo sea del tipo que presentamos en
nuestra definición, sino que se aceptan excepcionalmente partes derechas con la cadena vacía
, en cambio otros niegan tal posibilidad y otros aceptan una única producción de este tipo
con S como parte izquierda. Lo mismo sucede para las GRLI’s.
Nótese que si aceptamos como parte derecha la siguiente GRLD: G=({S}, {b}, P, S)
P:
S -->
Genera L(G)={}
En cambio si no aceptamos como parte derecha, es decir, siguiendo nuestra definición de
gramática regular, dichas gramáticas nunca podrán generar la cadena vacía.
Cuando se presentan este tipo de diferencias fuertes, no queda sino tomar posición, mejor si es
en base a argumentos razonablemente plausibles. Nosotros iremos tomando posición explícita
o implícitamente según se presenten los dilemas.
Para el caso que nos ocupa conservaremos nuestra definición y no aceptaremos como parte
derecha de ninguna producción en una GR.
22
Una justificación de ello es que si empezamos una derivación en la cadena S entonces, por la
forma de las producciones, la segunda cadena -obtenida al dar el primer paso de derivación-
será de longitud mayor o igual que |S|; a partir de esta segunda se puede obtener una
tercera en un siguiente paso de derivación que, por lo mismo, será de longitud mayor o igual
que la segunda, etc. Es decir, si tenemos la siguiente derivación genérica:
S => u2 => u3 => ... => un
Con nuestra toma de posición se tiene que: |S| |u2| |u3| ... |un|
Que denominaremos propiedad de no decrecimiento y que permite diseñar algunas
demostraciones teóricas sobre gramáticas en general –regulares y otras- que no tendrían éxito
si aceptamos como parte derecha, es decir, si la longitud de las cadenas en una derivación
crece, decrece o se mantiene arbitrariamente.
Estas demostraciones señalan propiedades que –a nuestro juicio- son más trascendentales que
la facilidad de incluir como parte derecha o la posibilidad importante de generar la cadena
vacía.
Lenguaje regular
Un lenguaje cualquiera L se dice que es un lenguaje regular si existe una GRLD o una GRLI
que genera dicho lenguaje (que eso nos baste por ahora, en realidad hay más casos en los que
a un lenguaje cualquiera se le puede decir regular).
Por ejemplo, a la pregunta si L={a} es o no un lenguaje regular podemos indicar que sí
describiendo la GRLD que genera este lenguaje: G=({S}, {a}, P, S) P: S --> a
A la pregunta si L={ ak / k 0 } es o no un lenguaje regular podemos indicar que no. Nuestra
definición de gramática regular no permite a las gramáticas regulares generar la cadena vacía,
y este lenguaje cuando k=0 incluye la cadena vacía. Ello sucede por nuestra toma de posición
para gramáticas; sin embargo, en general, ello no debiera ser un problema mayúsculo como se
verá cuando tratemos los autómatas finitos que sí aceptan .
L(G) lenguaje generado por G versus L lenguaje que creemos genera G ¿L=L(G)?
Hasta ahora hemos dejado de lado un hecho importante. En los ejemplos vistos no se ha
acompañado una razón, salvo el ejercicio mental, para evidenciar los lenguajes L(G) que se
han anotado.
Es claro que en gramáticas sencillas, tales como P={S --> b}, basta la simple inspección para
describir o concordar con L(G). Sin embargo, en otras gramáticas más largas y/o más
complejas no suele ser claro el lenguaje generado, y por tanto debe exigirse una
argumentación además de la explicitación de L(G).
23
Lamentablemente es común confundir una prueba del lenguaje generado por una gramática
con la descripción de algunas derivaciones. Para P={S --> aS, S --> a}, por ejemplo, es un
abuso escribir L(G)={ ak / k 0 } indicando que “... en efecto véase la siguiente derivación:
S=>aS=>aaS=>aaa ” y quizás algunas otras derivaciones. Es una audacia subtitular esto bajo
el epígrafe de prueba. En rigor, una, dos o varias derivaciones no prueban nada.
Ello es más visible cuando se pide escribir una gramática que genere L={algún lenguaje}; no
basta explicitar las producciones confiando en el autor de las mismas, debe acompañarse una
aclaración del rol de las producciones, una argumentación o más propiamente -en estricto
rigor- una demostración de que el lenguaje L(G) generado por la gramática a través de dichas
producciones, coincide con el lenguaje L.
Expliquemos la diferencia fuerte que existe entre L y L(G) a través de un ejemplo corto.
Suponga que tenemos el siguiente conjunto de producciones P={S --> bA, A --> a } y se nos
pide indicar el lenguaje que genera esta gramática, suponga que escribimos L(G)={a}.
Evidentemente –debido a la sencillez de la GRLD- ello no es cierto. Debido a esto, aunque la
literatura en general utiliza L(G) directamente, es más prudente indicar el lenguaje que genera
esta gramática a través de L –que denota un lenguaje-, así por ejemplo para esta gramática
alguien podría indicar que la misma genera el siguiente lenguaje L1={ab}; e incluso un tercero
podría sugerir que no, que lo que genera esta gramática es L2={b}.
Para cada L sugerido (L1, L2, etc. ) cada proponente tiene además la tarea de demostrar que
L=L(G).
Lo mismo sucede cuando se pide construir las producciones para un L dado. Digamos que se
pide construir una GRLI para L={(ab)i / i > 0} y se propone P={S --> Sa, S --> Sb, S --> a};
no basta este conjunto (erróneo dicho sea de paso) de producciones o cualquier otro, debe
además comprobarse que L=L(G).
Mostraremos algunos de prueba ejemplos en la segunda parte de este texto.
Por ahora nos bastará el trabajo mental y mencionar que es infrecuente que la literatura
demuestre el lenguaje generado para una gramática completa.
24
CAPÍTULO 3. AUTÓMATAS FINITOS
Así como hay gramáticas regulares lineales izquierdas y derechas que son diferentes pero que
en el fondo hacen lo mismo, también hay varios tipos de Autómatas Finitos (AF’s). Es usual
considerar principalmente los determinísticos y los no determinísticos pero no son los únicos.
Ya advertimos que a menudo debemos tomar posición respecto a varias cosas: en otros
lugares suelen usar q0 como estado inicial, nosotros haremos uso indistinto de q1, q0 u otro.
Tampoco permitimos el conjunto vacío como conjunto de estados.
En cambio F sí puede ser vacío en nuestro caso.
Ejemplo:
El siguiente es un Autómata Finito Determinístico (AFD) A:
A = ( K, , , q1, F )
={q1,q2,q3}
={a,b}
F={q2,q3}
:
(q1,a)=q2
(q1,b)=q3
(q2,a)=q3
(q2,b)=q1
(q3,a)=q1
(q3,b)=q3
Así como a los elementos de P se les llama producciones en una gramática, a los elementos de
se les llama reglas de transición.
Nuestro ejemplo tiene 6 reglas de transición, la penúltima regla de transición es (q3,a)=q1
25
Función total y determinismo
Sea (qi,a)=qj una regla de transición genérica.
qi se denomina estado de partida de la regla de transición.
qj se denomina estado de llegada de la regla de transición.
¿Cuántas reglas de transición debe tener A?
Esta es una pregunta importante en AFD’s.
Formalmente se ha indicado que es una función total, entonces, cuando ya tenemos definido
qué es K, qué es y cuántos elementos tienen, es obligatorio colocar |K|·|| reglas de
transición. |K| denota el número de estados, |denota el número de símbolos del alfabeto de
entrada, y · denota la multiplicación usual.
En el ejemplo 1 tenemos 3 estados y 2 símbolos en el alfabeto de entrada luego deben existir 6
reglas de transición.
Como es una función total y su dominio es (K X ), entonces debe haber una regla de
transición y solo una para todos y cada uno de los pares del tipo (qi,ak). Cuál estado de
llegada depende del lenguaje que estemos considerando, dejaremos de lado ello por ahora,
basta que sea un elemento de K.
Ejemplos:
El siguiente es un Autómata Finito Determinístico (AFD) A:
A = ( K, , , q1, F )
={q1,q2}
={a,b}
F={q1}
: tenemos |K|=2 y ||=2 luego deben haber 4 reglas de transición
(q1,a)=q2
(q1,b)=q2
(q2,a)=q1
(q2,b)=q1
26
El siguiente es un Autómata Finito Determinístico (AFD):
A = ( K, , , q1, F )
={q1,q2}
={1}
F={q1}
:
(q1,1)=q2
(q2,1)=q1
Como con T, convendremos que generalmente constará de letras minúsculas y/o dígitos.
Ejemplo erróneo:
Sea A = ( K, , , q1, F )
={q1,q2}
={a,b}
F={q1}
: tenemos |K|=2 y ||=2 luego deben haber 4 reglas de transición
(q1,a)=q2
(q1,a)=q1
(q2,a)=q3
(q2,b)=q1
La función de transición es errónea porque el par (q1,a) tiene dos reglas -no es función, no
respeta eso de una y sólo una regla de transición; además el par (q1,b) no tiene una regla de
transición asociada, no tiene estado de llegada, no respeta eso de que haya una regla para
todos y cada uno de los pares; finalmente q3 no es un estado en K.
a b
q1 q2 q2
q2 q1 q1
27
Una representación más popular y más estética apela a los grafos, dibujando lo que se llama
la red o diagrama de transición de estados.
Dicha gráfica puede ayudar a visualizar mejor un AFD –tanto él mismo como su
funcionamiento- y por eso es una herramienta importante, sin embargo, no es obligatorio
graficar un AFD.
Como dijimos básicamente se trata de dibujar un grafo donde los nodos son los estados y las
etiquetas son los símbolos de .
A cada estado de un AFD le corresponde un nodo, usualmente un círculo simple.
Si el estado en cuestión es además un estado final entonces le corresponde un círculo doble.
El estado inicial se identifica fácilmente pues es el estado q1 aunque también puede señalarse
con una flecha corta.
Si tenemos la regla de transición (qi,ak)=qj entonces dibujamos un arco con etiqueta ak desde
el nodo qi hasta el nodo qj
Nótese que -salvo excepciones que haremos notar- basta el diagrama de transición para
deducir F (los círculos dobles), K (todos los nodos), (las etiquetas de los arcos) y las
transiciones (el sentido de los arcos), es decir, que podemos presentar un AFD A mostrando
sólo su gráfica.
ii)
1
q1 q2
q2 q1
iii)
28
ii)
a b
q1 q1 q1
iii)
Como ya hicimos en la primera gráfica, cuando hay más de un arco yendo de un mismo nodo
de partida a un mismo nodo de llegada, es usual utilizar un solo arco y poner todas las
etiquetas que correspondan separadas por una barra (o por comas o por algún otro separador).
Luego es más usual este tipo de diagrama para este ejemplo:
Una gramática regular genera cadenas, en cambio un AFD acepta o reconoce cadenas.
Para describir cuál el mecanismo de funcionamiento para este reconocimiento necesitamos
algunos conceptos previos.
29
Movimiento(s) en un AFD
Así como usábamos => para denotar un paso de derivación usaremos |-- para denotar un
movimiento en un AFD.
Con un movimiento pasamos de una d.i. a otra d.i.
Ejemplo:
Si tenemos la regla de transición (q1,b)=q2
podemos dar el siguiente movimiento (q1,bab) |-- (q2,ab)
Luego de un movimiento la d.i. actual cambia a otra d.i. que se obtiene así:
a) el estado de esta nueva d.i. es el estado de llegada de la regla de transición que hemos
usado.
b) la cadena de esta nueva d.i. es semejante a la cadena de la d.i. actual (en negrita) excepto
su primer símbolo que se omite.
Otros ejemplos:
Si tenemos la regla de transición (q1,b)=q2
podemos dar el siguiente movimiento (q1,bb) |-- (q2,b)
30
Ejemplos:
Trabajando con el AFD A = ( {q1,q2}, {a,b}, , q1, {q2} )
:
(q1,a)=q2
(q1,b)=q2
(q2,a)=q1
(q2,b)=q1
Nótese que cuando ya no quedan símbolos que leer o consumir en la cadena de entrada, ese
hecho se denota por y el AFD ya no puede dar más movimientos.
Si i) y ii) se cumplen, finalmente debe observarse en qué estado quedamos (cuál es el estado
de la última d.i.), si es un estado final se dice que la cadena de entrada es aceptada o
reconocida por el AFD, en otro caso se dice que no es aceptada (o lo que es lo mismo, que es
rechazada).
Formalmente una cadena u es aceptada por el AFD si y solo si (q1,u) |--* (qi,) y qi F
31
Ejemplos:
Trabajando trabajando con el AFD A = ( {q1,q2}, {a,b}, , q1, {q1} )
:
(q1,a)=q2
(q1,b)=q2
(q2,a)=q1
(q2,b)=q1
Con una cadena cualquiera y el estado q1 o cualquier otro estado indicado, es muy fácil ir
consumiendo la cadena de entrada desde dicho estado indicado siguiendo los arcos del
diagrama de transiciones y ver en qué estado se acaba. Es ilustrativo hacerlo.
Sólo falta indicar un caso especial: ¿ qué pasa si la cadena de entrada es la cadena vacía ?
En este caso el AFD no puede ir más allá de su d.i. inicial pero está permitido anotar lo
siguiente: (q1,) |--* (q1,). El AFD termina en la d.i. en la que ha empezado (¡ya está ahí!),
de manera que si el estado inicial es un estado final entonces se dice que la cadena vacía es
aceptada por el AFD (a diferencia de las gramáticas regulares que no pueden generar ).
32
La función *: otra notación frecuente
Otra notación muy popular y muy útil para asuntos teóricos, que se usa para indicar cuál es el
último estado al que llega un AFD después de consumir toda la cadena de entrada partiendo
de un estado cualquiera es así:
*(qi,u)=qj
Para indicar que partiendo del estado qi y consumiendo toda la cadena u se llega
-finalmente- al estado qj.
Ejemplos:
Se puede escribir (q2,aaa) |--* (q1,) o también *(q2,aaa)=q1
Se puede escribir (q1,aa) |--* (q1,) o también *(q1,aa)=q1
Se puede escribir (q1,abb) |--* (q2,) o también *(q1,abb)=q2
En realidad * es una función denotada por *: K X *---> K, cuya definición recursiva es
*(qi,) = qi
*(qi,ua) = (*(qi,u),a) donde u*a
Ejemplos de uso:
Para el AFD A cuyo diagrama es el siguiente:
33
v)*(q1,baba) = (*(q1,bab),a) por definición, u = bab
= (q2,a) por iv)
= q3 por
A semejanza de lo que sucede con gramáticas existen dos problemas básicos: dado un AFD A
decir qué es T(A); y dado un lenguaje L construir un AFD que acepte dicho lenguaje.
Presentaremos algunos ejemplos sobre ambos aspectos.
Ejemplos:
Para el AFD A = ( {q1}, {a,b}, q1{ } )
: (q1,a)=q1 (q1,b)=q1
T(A)={ }
Sea cual fuere la cadena u con la que trabajemos ninguna de ellas llegará a un estado
final porque no hay estados finales ( F={ } ).
34
Se pide construir un AFD A que acepte L={a,b}-{}
Una solución es A = ( {q1,q2}, {a,b}, q1{q2} )
: (q1,a)=q2 (q1,b)=q2 (q2,a)=q2 (q2,b)=q2
De manera análoga a lo que sucede con las gramáticas regulares, el número de símbolos y de
estados en un AFD y de éstos cuáles deben/pueden ser finales, depende del lenguaje que
estemos considerando.
35
*(*(qi,u),v)=*(p,v) trabajando con *(qi,u)=p
=*(p,wa) pues v=wa
=(*(p,w),a) por definición de *
=(*(*(qi,u),w),a) trabajando con *(qi,u)=p
=(*(qi,uw),a) por hipótesis inductiva pues |w|=k
=*(qi,uwa) por definición de *
=*(qi,uv) pues v=wa
Ejemplo:
Sea el Autómata Finito No Determinístico (AFN) A = ( K, , d, q1, F )
={q1,q2}
={a,b}
F={q2}
d:
d(q1,a)={q1,q2}
d(q2,b)={q2}
Hay varias semejanzas entre los AFD’s y los AFN’s: el uso de diagramas de transición, el uso
de descripciones instantáneas, la aceptación o rechazo de cadenas, para mencionar algunas.
Pero tienen también importantes diferencias, veamos las principales:
En los AFD’s: de un par (estado, símbolo) se llega a un estado (escrito suelto, sin llaves)
En los AFN’s de un par (estado, símbolo) se llega a un conjunto de estados (obviamente
escrito entre llaves).
36
En los AFD’s al estar situados en un estado y al consumir un símbolo de una cadena de
entrada el siguiente estado está determinado irremediablemente (por eso se llaman
Determinísticos).
En los AFN’s al estar situados en un estado y al consumir un símbolo de una cadena de
entrada -a veces- se puede ir a uno u otro (u otro, etc.) estado, según como esté definida la
regla de transición. En el ejemplo de arriba estando en q1 y consumiendo el símbolo a,
podemos pasar ya sea al propio q1 o a q2.
Una forma que adoptamos para diferenciar AFD’s de AFN’s es utilizar d para la función de
transición en AFN’s y en AFD’s.
Ejemplos:
Con este AFN (el mismo del último ejemplo)
37
para la d.i. (q2,bb), el único movimiento que puede darse utilizará la regla de transición
d(q2,b)={q2}, luego de lo cual la siguiente d.i. será (q2,b) hecho que hemos estado
representado así: (q2,bb) |-- (q2,b).
En cambio para la d.i. (q1,aa) el AFN puede dar cualquiera de los siguientes dos movimientos
lícitos utilizando la regla de transición d(q1,a)={q1,q2}
i) (q1,aa) |-- (q1,a)
ii) (q1,aa) |-- (q2,a)
Puede ser útil representar estas varias alternativas a través de un árbol de transiciones que para
nuestro ejemplo sería así:
|-- (q1,a)
/
(q1,aa)
\
|-- (q2,a)
Representaremos -a través de estos árboles de transiciones- un caso más largo, con el mismo
AFN, partiendo de la misma d.i. (q1,aa)
|--1 (q1,)
/
|--1 (q1,a)
/ \
(q1,aa) |--2 (q2,)
\
|--2 (q2,a)
Donde hemos anotado con un subíndice el número de regla de transición que se utiliza para
dar un movimiento lícito. Este árbol muestra que todas las siguientes transiciones son
legítimas:
a) (q1,aa) |--* (q1,)
b) (q1,aa) |--* (q2,)
c) (q1,aa) |--* (q2,a)
El inciso b) muestra que partiendo del estado inicial con la cadena aa podemos llegar a un d.i.
que evidencia que se ha consumido toda la cadena y que se ha arribado a un estado final: q2.
Es decir, la cadena aa es aceptada por el AFN.
Para descubrir esto no basta con hacer alguna serie de movimientos lícitos -por ejemplo sólo
los del inciso a)-, deben escudriñarse todas las posibles transiciones, cuando menos
mentalmente.
También nótese, como muestra el inciso c), que como formalmente un movimiento exige
consumir un símbolo y un estado de llegada, es posible -siguiendo cierto camino del árbol de
transiciones- que un AFN ya no puede dar ningún movimiento, no pueda ir a ningún otro
estado.
38
El caso extremo de esto es que un AFN no pueda dar ni siquiera un movimiento, como sucede
con nuestro AFN si partiera de la d.i. (q1,bbb). En situaciones como esta lo único que
podemos escribir es lo siguiente:
(q1,bbb) |--* (q1,bbb).
Una cadena de entrada es aceptada en un AFN si partiendo del estado inicial q1 es posible
llegar a un estado final con alguna serie de movimientos consumiendo toda la cadena. Fíjese
que para decidir si una cadena es aceptada o no debemos analizar todas, absolutamente todas
las transiciones posibles del árbol de transiciones.
La función d*
Otra notación muy útil para asuntos teóricos, usada para indicar de un modo más apropiado
que en un AFN se puede llegar a un conjunto de estados, incluido el vacío, partiendo de un
estado y con una cadena u de entrada es así:
d*(qi,u)={conjunto de todos los estados a los que se puede llegar partiendo de qi
consumiendo todos los símbolos de u}
Ejemplos:
Con el AFN
d*(q1,aa)={q1,q2}
d*(q1,bbb)={ }
En realidad d* es una función, denotada por d*: K X *---> 2K, cuya definición recursiva es
d*(qi,) = {qi}
d*(qi,ua) = d(p,a)
p d *( q i ,u )
39
Ejemplos:
Con el AFN
=
p {q1}
d(p,a) por i)
=
p {q1 ,q 2 }
d(p, b) por ii)
Ejemplos:
40
Sea el AFN A = ({q1,q2}, {a,b}, d, q1, {q2} )
d:
d(q1,a)={q1,q2}
d(q1,b)={q1}
T(A)={ua / u {a,b}*}
T(A)={ab}
T(A)={u / u {a,b}*, u contiene por lo menos una vez la subcadena “aa” o la subcadena “bb”}
Como siempre los problemas básicos son dos: dado un AFN A indicar qué es T(A); y dado un
lenguaje L construir un AFN A que acepte L.
41
AUTÓMATAS FINITOS NO DETERMINÍSTICOS CON TRANSICIONES VACÍAS
(-AFN’S)
Un Autómata Finito No determinístico con transiciones vacías (o con lambda transiciones, o
con -transiciones) es una quíntupla A = ( K, , d, q1, F ) donde
K: conjunto finito, no vacío, de estados
: alfabeto de entrada
d: función de transición ( se denota así d: K X ( {}) --> 2K )
q1: estado inicial del AFN q1 K (es decir, q1 debe estar en K)
F: conjunto de estados finales F K
Ejemplo:
Sea el AFN A = ( {q1,q2,q3}, b,c}, d, q1, {q1,q2,q3})
d:
d(q1,)={q2,q3}
d(q2,b)={q2}
d(q3,c)={q3}
De este modo los -AFN’s son prácticamente lo mismo que los AFN’s sólo que permiten la
flexibilidad de incluir etiquetas en sus arcos -si queremos apoyarnos en los diagramas de
estado-, ó más concretamente, pueden haber reglas de transición del tipo d(qi,)={qj}, o
cualquier otro conjunto de llegada. En este caso no es un símbolo de y la cadena de
entrada permanece tal cual cuando usamos estas -transiciones, es decir, no se consume
ningún símbolo al transitar por etiquetas .
Los otros formalismos y notaciones (d*, |--, etc.) se siguen usando y tienen significados
análogos.
-cierre
La inclusión de transiciones vacías, que en el caso de los diagramas se representa con
etiquetas , adiciona cierta complejidad a los cálculos. Por ejemplo si nos encontramos en el
estado qi y consumimos un símbolo ak, el conjunto de estados a los que podemos arribar debe
contemplar la posibilidad de ir de un estado a otro -y aún a otros- sin consumir símbolos, sólo
‘consumiendo’ la cadena , antes o después de consumir ak.
42
Debemos poder calcular a qué otros estados se llega partiendo de un estado y utilizando sólo
-transiciones. En el -AFN recién graficado partiendo de q1 podemos llegar al propio q1
debido a que ya estamos ahí y también, utilizando sólo -transiciones sin consumir símbolos
de entrada, podemos llegar a q2 y a q3, denotaremos esto así:
-cierre({q1}) = {q1,q2,q3}
Que nos dice -repetimos- que estando en q1 podemos llegar, sin consumir símbolos de entrada,
a q1, a q2 y a q3; es importante enfatizar que de un estado cualquiera qi siempre es posible
llegar a sí mismo sin consumir símbolos de entrada simplemente porque ya estamos ahí (ya
‘hemos llegado’), por eso q1 pertenece al -cierre({q1})
Podemos extender esta idea para calcular el -cierre(C) donde C es un conjunto de estados:
-cierre({}) = {}
-cierre({q}) = { conjunto de todos los estados a los que podemos arribar, incluido q,
utilizando sólo -transiciones sin consumir símbolos de entrada partiendo
de q } Es decir,
-cierre({q}) = {q} { p / partiendo de q se arriba a p utilizando sólo -transiciones }
-cierre(C) =
q C
-cierre({q})
Y aún una manera adicional de tipo matricial de calcular el -cierre(C) requiere recordar
algunos elementos básicos de la relaciones de equivalencia y la partición de un conjunto.
43
Clausura reflexiva transitiva de una relación
Sea R una relación definida sobre un conjunto B y denotemos por ° la composición de
relaciones. Se sabe que la composición de R consigo misma puede repetirse varias veces
dejando la idea de potencia de una relación:
R0 = IB (la relación de identidad sobre B)
R = R ° R (n 0)
n+1 n
La potencia de una relación ofrece una manera de definir la clausura transitiva de una relación
-denotada por R+- así:
R+ =
i>0
Ri
Para el caso del -cierre(C), podemos construir una matriz de |K| x |K| representando la
relación R K X K que relaciona el estado qi con el estado qj si existe una -transición
explícita de qi a qj.
Donde cada fila y cada columna corresponde a un estado, un 0 indica que los estados no están
relacionados y un 1 que si.
Para el siguiente -AFN
la matriz R será:
0 1 1
R = 0 0 0
0 0 0
R+, la clausura transitiva de R, relaciona los estados que son accesibles desde otro con sólo
-transiciones: (qi,qj) R+ si desde qi puede arribarse a qj con sólo -transiciones.
Nótese que R+ no relaciona qi consigo mismo a no ser que haya una -transición explícita de
qi a qi.
44
R1 = R
Ri+1 = Ri + (Ri * Ri)
Si Ri+1 = Ri entonces R+ = Ri
donde + y * representan la suma boolena y producto booleano de matrices.
Sin embargo para el cálculo del -cierre(C) necesitamos incluir cada estado de C aunque no
hayan -transiciones explícitas de qi a qi, porque el -cierre(C) calcula los estados que son
alcanzables desde cualquier estado de C con la cadena .
Como R+ relaciona los estados que son alcanzables desde otro con sólo -transiciones
explícitas, obtendremos el -cierre(C) así:
R* = R+ + IK
donde + representa la suma boolena de matrices.
Ejemplos:
Para el siguiente -AFN:
Calculamos el -cierre({q1})
De acuerdo a la primera forma tenemos:
B0 = {q1}
B1 = B0 {p / qj B0 y p d(qj,)}
= {q1} {p / qj {q1} y p d(qj,)}
= {q1} {p / p d(q1,)}
= {q1} {p / p {q2,q3}}
= {q1} {q2,q3} = {q1,q2,q3}
B2 = B1 {p / qj B1 y p d(qj,)}
= {q1,q2,q3} {p / qj {q1,q2,q3} y p d(qj,)}
= {q1,q2,q3} { p / p d(q1,)} { p / p d(q2,)} { p / p d(q3,)}
= {q1,q2,q3} {q2,q3} {} {} = {q1,q2,q3}
Como B2 = B1 entonces Bn = B1 y por lo tanto -cierre({q1}) = B1 = {q1,q2,q3}
45
Por el modo matricial tenemos:
0 1 1
1
R = R = 0 0 0
0 0 0
R2 = R1 + (R1 * R1)
0 1 1 0 1 1 0 1 1 0 1 1 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0
= + ( 0 0 0 * 0 0 0 ) = + = 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Como R2 = R1 entonces R+ = R1
0 1 1 1 0 0 1 1 1
R* = R+ + IK = 0 0 0 + 0 1 0 = 0 1 0
0 0 0 0 0 1 0 0 1
El -cierre({q1}) = {q1,q2,q3}
Pues la fila 1 de R* tiene un 1 en las columnas 1, 2 y 3.
El cálculo de R* nos facilita otros cálculos, siguiendo el mismo procedimiento tenemos:
-cierre({q2,q3}) = {q2,q3}
Calculamos el -cierre({q2})
B0 = {q2}
B1 = B0 {p / qj B0 y p d(qj,)}
= {q2} {p / qj {q2} y p d(qj,)}
= {q2} {p / p d(q2,)}
= {q2} {p / p {q4}}
= {q2} {q4} = {q2,q4}
B2 = B1 {p / qj B1 y p d(qj,)}
= {q2,q4} {p / qj {q2,q4} y p d(qj,)}
= {q2,q4} { p / p d(q2,)} { p / p d(q4,)}
= {q2,q4} {q4} {q3} = {q2,q3,q4}
B3 = B2 {p / qj B2 y p d(qj,)}
= {q2,q3,q4} {p / qj {q2,q3,q4} y p d(qj,)}
= {q2,q3,q4} { p / p d(q2,)} { p / p d(q3,)} { p / p d(q4,)}
= {q2,q3,q4} {q4} {q3,q4} {q3} = {q2,q3,q4}
46
Como B3 = B2 entonces Bn = B2 y por lo tanto -cierre({q2}) = B2 = {q2,q3,q4}
Por el modo matricial tenemos:
0 0 0 0
0 0 0 1
R1 = R =
0 0 1 1
0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0
0
0 0 1 0 0 0 1 0 0 0 1
R2 = R1 + (R1 * R1) = + ( * )
0 0 1 1 0 0 1 1 0 0 1 1
0 0 1 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0
0 1 0 0 0 1 1
= + =
0 0 1 1 0 0 1 1 0 0 1 1
0 0 1 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 1 1 0 0 1 1
R3 = R2 + (R * R ) =
2 2
+ ( * )
0 0 1 1 0 0 1 1 0 0 1 1
0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 1 1 0 0 1 1
= + =
0 0 1 1 0 0 1 1 0 0 1 1
0 0 1 1 0 0 1 1 0 0 1 1
Como R3 = R2 entonces R+ = R2
0 0 0 0 1 0 0 0 1 0 0 0
0
0 1 1 0
1 0 0 0 1 1 1
R* = R+ + IK = + =
0 0 1 1 0 0 1 0 0 0 1 1
0 0 1 1 0 0 0 1 0 0 1 1
El -cierre({q2}) = {q2,q3,q4}
Pues la fila 2 de R* tiene un 1 en las columnas 2, 3 y 4.
El cálculo de R* nos facilita otros cálculos, siguiendo el mismo procedimiento tenemos:
-cierre({q1}) = {q1}
-cierre({q3}) = {q3,q4}
-cierre({q4}) = {q3,q4}
El -cierre({q1,q4}) = {q1,q3,q4}
47
La función d*
d*(qi,u)={conjunto de todos los estados a los que se puede llegar partiendo de qi
consumiendo todos los símbolos de u}
Nótese que ahora deben considerarse las -transiciones.
d* es una función denotada por d*: K X *---> 2K y cuya definición recursiva es
d*(qi,) = -cierre({qi})
d*(qi,ua) = -cierre d(p,a)
p d*( q i ,u)
Ejemplos:
Para el siguiente -AFN:
48
= {q3}
d*(q1,cc) = -cierre d(p,c) = -cierre
d(p,c) = -cierre(d(q3,c))
p d*( q1 ,c) p {q 3}
-cierre({q3}) = {q3}
Así en nuestro primer ejemplo como d*(q1,bcb) = {}, tenemos que d*(q1,bcb)F =, luego
la cadena bcb es rechazada por el -AFN. También como d*(q1,cc) = {q3}, tenemos que
(d*(q1,cc)F), luego la cadena cc es aceptada por el -AFN.
En nuestro segundo ejemplo, es claro que (d*(q1,ab)F){q1,q3,q4} {q1,q4}{q1,q4},
luego (d*(q1,ab)F) y por lo tanto la cadena ab es aceptada por este segundo -AFN.
Como siempre los problemas básicos son dos: dado un -AFN A indicar qué es T(A); y dado
un lenguaje L construir un -AFN A que acepte L.
49
Ejemplos:
Para el siguiente -AFN
=
p {q i }
d(p,a) por definición recursiva de d* ( es decir, d*(qi,)={qi} )
50
= d(qi, a)desarrollando la unión
iv) Dado únicamente el diagrama de transición, como el siguiente:
sin más datos, puede resultar ambiguo indicar si dicho diagrama corresponde a un -AFN, a
un AFN o a un AFD, por ello cuando un diagrama no sea suficientemente claro es exigible
indicar la función o explicitar de qué tipo de autómata finito se trata.
51
CAPÍTULO 4. EXPRESIONES REGULARES
Las expresiones regulares (e.r.) tienen un importante desarrollo teórico, constituyen además
otro medio para denotar lenguajes y conjuntos regulares.
Las e.r. de un alfabeto y los lenguajes que denotan se definen como sigue:
es una e.r.
es una e.r.
Para cada a , a es una e.r.
Si r y s son e.r. entonces (r+s), (r·s) y (r*) son también e.r.
Se puede indicar un lenguaje utilizando -como hasta ahora- notación en potencias, con
operaciones entre lenguajes, etc.; pero también podemos utilizar e.r., por ejemplo:
Un problema típico es escribir una e.r. que denote un lenguaje descrito literalmente y que
tiene ciertas restricciones.
52
Ejemplos:
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* donde inmediatamente luego de
toda b aparece una a: (a+ba)*
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* que contengan la subcadena bb
por lo menos una vez: (a+b)*bb(a+b)*
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* que contengan la subcadena
bb exactamente una vez: (ba+a)*bb(a+ab)*
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* que no contengan la subcadena
bb: (a+ba)*(b+)
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* que no contengan la subcadena
aa ni la subcadena bb: (b+)(ab)*(a+)
Escriba una e.r. que denote el conjunto de cadenas en {a}* que tiene un número impar de a’s:
a(aa)*
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* que tiene un número par de a’s:
(b*ab*ab*)* + b*
Escriba una e.r. que denote el conjunto de cadenas en {a,b}* cuya longitud es divisible por 4:
((a+b)(a+b)(a+b)(a+b))*
Escriba una e.r. que denote el conjunto de cadenas en {0,1}* tal que si una cadena contiene la
subcadena 00 no debe contener la subcadena 11: (1+01)*(0+) + (0+10)*(1+)
Escriba una e.r. que denote el conjunto de cadenas en {0,1}* que contenga la subcadena 11
exactamente una vez pero no la subcadena 00: (0+)(10)*11(01)*(a+)
Escriba una e.r. que denote el conjunto de cadenas en {0,1}* que contenga la subcadena 11
por lo menos una vez pero no la subcadena 00: (1+01)(01)*1(1+01)*(0+λ)
53
CAPÍTULO 5. GRAMÁTICAS LIBRES DE CONTEXTO
Ejemplos:
Esta es la apariencia de una GLC G=({S,A,B},{a,b},P,S)
P:
S --> A
S --> ABBB
A --> aba
A --> aBBAaaA
B --> b
54
Sea la GLC G=({S},{a,b},P,S)
P:
S --> aSb S --> Sb S --> abb
L={aibk / k>i, i>0}
Árboles de derivación
Además de la (relación de) derivación que conocemos denotada por =>, podemos realizar el
gráfico de una derivación utilizando árboles en lo que se denomina árboles de derivación.
Sea G una GLC, un árbol de derivación A es aquel donde:
i) Cada nodo o vértice tiene una etiqueta en (N T).
ii) Si un nodo no es hoja entonces su etiqueta está en N y lo denominaremos nodo interior
(salvo el caso del árbol con un solo nodo etiquetado con S).
iii) Si el nodo ni con etiqueta X tiene como hijos a los nodos nj1,..., njm –de izquierda a
derecha- con etiquetas ej1,...,ejm respectivamente, entonces X-->ej1...ejm P.
55
Si la etiqueta del nodo raíz es X, podemos referirnos al árbol A como árbol X.
A la cadena conformada por las etiquetas de los nodos hoja del árbol A, leídas de izquierda a
derecha, la llamaremos producto del árbol de derivación.
Un árbol de derivación con su nodo raíz etiquetado con S (símbolo raíz de G) y con producto
wT+, se dice que es un árbol de derivación completo (conocido también como parse tree).
Ejemplo:
Sea la GLC G=({A,B},{a,b},P,S)
P:
S -->AB A --> aA B --> bB
A -->a B --> b
La cadena aabbb tiene la siguiente derivación:
S=>AB=>AbB=>AbbB=>Abbb=>aAbbb=>aabbb
Y el árbol de derivación correspondiente A es:
Ejemplo:
Si en el árbol de derivación recién graficado A se denominan los nodos por niveles de arriba a
abajo y de izquierda a derecha así: n1,n2,...,n11, la etiqueta del nodo n7 es B, y el subárbol An7
con producto bb es este:
56
Operación de reemplazo en árboles
Para una GLC G:
Sea A un árbol de derivación uno de cuyos nodos (n) tiene la etiqueta No Terminal X.
Sea B otro árbol de derivación cuya raíz también tiene la etiqueta X.
Reemplazar B en el nodo n de A es reemplazar el subárbol An del árbol A por el árbol B, es
decir, borrar en el árbol A el nodo n junto a todos sus descendientes (etiquetas y arcos
incluidos) y en su lugar colocar el árbol B.
Es claro –de la definición de árbol de derivación- que el resultado de reemplazar B en (el nodo
n de) A es un árbol de derivación también.
Ejemplo: Con P:
S --> AB A --> aA B --> bB
A --> a B --> b
tenemos el siguiente árbol de derivación B:
57
Dado un árbol de derivación A dado, dicho árbol puede estar asociado no sólo a una
derivación sino a varias.
Ejemplo: Con P:
S --> AB
A --> a
B --> b
Dado el árbol de derivación A:
Sin embargo, si introducimos el concepto de derivación más a la izquierda que limita la forma
de derivar, dado un árbol de derivación A con etiqueta A en su raíz y con producto u, la
derivación A=>*u es única.
Ejemplo: Con P:
S --> A | ABBB
A --> aba | A --> aBBAaaA
B --> b
Dado el árbol de derivación A:
58
S=>ABBB=>abaBBB=>ababBB=>ababbB
Es una derivación más a la izquierda, donde hemos puesto en negrita el No Terminal más a la
izquierda en cada paso de derivación. Nótese que no es necesario que una derivación más a la
izquierda termine en cadenas de sólo Terminales.
Formalmente, una derivación u=>*w es una derivación más a la izquierda si cada paso de
derivación es más a la izquierda. Un paso de derivación u=>w es más a la izquierda si u=yXz,
w=yz, X-->P, z(N T)*, yT*.
La derivación más a la derecha se define de manera análoga.
Ambigüedad
Hay otro concepto muy utilizado sobre todo en compilación y reconocimiento de cadenas.
Ya vimos que varias derivaciones distintas (no necesariamente más a la izquierda) A=>*u
pueden tener el mismo árbol de derivación como gráfica.
También dijimos que a un árbol de derivación A con producto u y cuya raíz tiene la etiqueta
A, se asocia una única derivación más a la izquierda A=> *u.
Ahora queremos hacer notar que en una GLC G para una misma cadena u si empezamos a
hacer no árboles sino derivaciones -e incluso si sólo efectuamos derivaciones más a la
izquierda- podemos obtener dos o más derivaciones que tienen árboles de derivación distintos
(dos o más).
Ejemplos:
Sea G=({S},{a,b,c,},P={S-->SbS, S-->ScS, S-->a},S)
La derivación S=>*abaca puede hacerse así (no son derivaciones más a la izquierda todas):
S=>SbS=>SbScS=>SbSca=>Sbaca=>abaca
S=>ScS=>SbScS=>abScS=>abacS=>abaca
Los correspondientes árboles de derivación son.
En este caso, para una misma cadena, se obtuvieron árboles de derivación distintos.
Sea G=({S,A},{a},P={S-->AA,A-->aSa,A-->a},S)
59
Se obtienen estos dos árboles de derivación para la misma cadena derivada S=>*aaaaa:
El valor del resultado de la expresión a la derecha del operador de asignación (:=) tiene,
ambiguamente, dos interpretaciones posibles: b+(c*a) ó (b+c)*a.
60
Se dice que una GLC G es ambigua cuando hay dos o más árboles de derivación distintos para
una misma cadena.
El último ejemplo muestra que la ambigüedad no es una característica deseable en una GLC.
A veces es posible -para una GLC ambigua- encontrar otra GLC equivalente pero que no sea
ambigua.
Ejemplos:
Sea la GLC G’=({S,A,B},{a},{S-->A,S--> B,A-->a,B-->a},S)
En una GLC G no ambigua para una cadena en L(G) hay sólo un árbol de derivación.
En cambio si todas las GLC’s para un lenguaje L dado son ambiguas, se dice que L es
inherentemente ambiguo.
61
Hay lenguajes (por ejemplo L={aibicj / i,j>0}{aibjcj / i,j>0}) que son inherentemente
ambiguos pero la demostración de ello suele ser bastante extensa.
Finalmente existen pruebas (por ejemplo utilizando el denominado Teorema De Greibach, que
no exponemos) de que el problema de determinar si un lenguaje libre de contexto es
inherentemente ambiguo o no es indecidible.
Ejemplos:
En la GLC G=({S,X},{a},{S-->a,X-->b},S) el No Terminal X es inaccesible.
En la GLC G=({S,X},{a,b},{S-->a,S-->X,X-->Xa},S) el No Terminal X es inútil.
Sea la GLC G=({S,X,Y,W,Z},{a,b},P,S)
P:
S --> aS S --> Y S --> bbZ
Y --> a Z --> bZ
X --> Xa X --> b
W --> WaW
S es útil; Y es accesible y útil; X es útil pero inaccesible; Z es accesible pero inútil; W es
inaccesible e inútil; la producción S-->Y es renombradora.
62
Formas normales
Es posible que una GLC no sólo cumpla la definición sino que además posea otras
restricciones en sus partes derechas, así por ejemplo una GLC se dice que es lineal (derecha)
si todas sus producciones son de la forma A-->wX, con A,XN y wT*. Otras restricciones
han dado paso a lo que se llaman formas normales.
1) Forma normal de Chomsky (FNCH)
Una GLC G se dice que está en FNCH si todas sus producciones son de la forma:
A-->BC A,B,CN ó A-->d AN, dT
Es decir las partes derechas deben tener o un Terminal o dos No Terminales.
2) Forma normal de Greibach (FNG)
Una GLC G se dice que está en FNG si todas sus producciones son de la siguiente forma :
A-->a AN, a, N*
Es decir las partes derechas son de un Terminal seguido de 0, 1 o más No Terminales
3) Forma normal cuadrática de Greibach (2FNG)
Se dice que una GLC G está en 2FNG si todas sus producciones son de la forma:
A-->a AN, a, N*, || < 3
Exactamente lo mismo es decir que todas sus producciones son de la forma:
A-->a ó A-->aB ó A-->aBC A,B,CN, a
Ejemplos:
La GLC G=({S,A,B,X},{a,b},P,S) está en FNCH
P:
S --> AX
X --> SB
S --> AB
A --> a
B --> b
Es claro que toda GLC G que esté en 2FNG está en FNG. La inversa no es cierta, por ejemplo
la GLC G=({S},{a},{S-->aSSSS,S-->a},S) está en FNG pero no en 2FNG.
63
CAPÍTULO 6. AUTÓMATAS DE PILA (AP)
Además de los estados K y los alfabetos N y T, los AP’s añaden una estructura de datos que
servirá como memoria: la pila. Hay una variedad de ellos, los más conocidos son los
Autómatas de Pila por pila vacía (AP) y los Autómatas de Pila por estado final (APe.f.)
Ejemplo:
La apariencia de un AP A es así:
A=({q0,q1},{a,b},{Z,X},,q0, Z,{})
(q0,a,Z)={(q0,XZ)}
(q0,a,X)={(q0,XX)}
(q0,b,X)={(q1,)}
(q1,b,X)={(q1,)}
(q1,,Z)={(q2,)}
Entre las llaves es posible que hayan varios pares en vez de uno (por ejemplo podría haber
otro AP con una regla de transición así (q0,a,X) = {(q0,XX), (q1,XZ), (q2,)) o ninguno (las
reglas de transición que lleguen al conjunto vacío no se escriben).
Nosotros usaremos a veces q0 para el estado inicial, a veces q1 y a veces cualquier otro
nombre, esto no debe causar confusión siempre que se indique cuál es el estado inicial.
64
Un AP siempre empieza su funcionamiento en el estado inicial y con la pila conteniendo
únicamente su símbolo inicial, de manera que si alimentamos al AP con la entrada u al
principio la d.i. inicial será (q0,u,), fíjese como el tercer componente describe la pila
conteniendo sólo Z, por ejemplo si u=aaabbb, la d.i. inicial es (q0,aaabbb,).
Movimientos
Indicaremos con el símbolo |-- el hecho de que un AP dé un movimiento, que es con el que
pasamos de una d.i. a otra d.i. (|-- no es sino el nombre de una relación entre d.i.’s).
En los AP’s hay una especie de ‘control avanzado’ sobre la cinta de entrada de manera que no
es necesario consumir un símbolo de entrada para dar un movimiento. El cambio de estado -y
lo que le sucede a la pila- depende (además del estado actual y, tal vez, del símbolo que
estamos leyendo en la entrada) del contenido de la pila, específicamente del símbolo en el
tope de la pila.
Los movimientos son básicamente de dos tipos:
i) Movimiento tipo 1
Sean (qi,aw,X) y (qj,w,) dos d.i. con *, X a w*, qi,qjK; escribiremos
(qi,aw,X) |-- (qj,w,) si (qj,)(qi,a,X)
Y diremos que hemos dado un movimiento tipo 1 (aquel donde se usa una regla de transición
con un símbolo diferente de como segundo elemento de la preimagen, que hemos resaltado
en negrita), por ejemplo (q0,a,X)={(q0,XX)} ó (q1,a,X)={(q1,)}.
Para realizar un movimiento utilizando esta regla de transición es necesario que el estado
actual sea qi, estar analizando/leyendo una a en la cadena de entrada y tener en el tope de la
pila una X. Cuando el AP da un movimiento tipo 1 pasa lo siguiente:
Consume el símbolo a de la entrada y la cabeza lectora avanza un símbolo a la derecha en la
cinta de entrada (es claro que si hay más de un par de imágenes entre llaves se tiene que hacer
una elección de qué par utilizar, genéricamente se elige (qj,)); el estado actual cambia a qj; y
el tope de la pila X se reemplaza por (hay quien explica esto diciendo que el AP saca X de la
pila colocando en su lugar).
Por ejemplo, con la transición (q1,a,X)={(q2,YY)} y la d.i. (q1,abbab,XZ), el siguiente
movimiento tipo 1 es posible: (q1,abbab,XZ)|--(q2,bbab,YYZ).
Fíjese que el estado actual cambia de q1 a q2; que se ha consumido a de manera que lo que
queda por analizar de la cadena de entrada es bbab; que en la pila el tope X se reemplaza por
YY; y lo que estaba debajo del tope (Z en nuestro caso) se mantiene tal cual.
ii) Movimiento tipo 2 ó -movimiento
Sean (qi,w,X) y (qj,w,) dos d.i. con *, X w*, qi,qjK; escribiremos
(qi,w,X) |-- (qj,w,) si (qj,)(qi,,X)
Y diremos que hemos dado un movimiento tipo 2 o un -movimiento (aquel donde se usa una
regla de transición con como segundo elemento de la preimagen, que hemos resaltado en
negrita), por ejemplo (q0,,X)={(q0,XX)} ó (q1,,X)={(q1,)}.
Para realizar un movimiento utilizando esta regla de transición es necesario que el estado
actual sea qi y tener en el tope de la pila una X.
65
Nótese que no interesa qué se está analizando/leyendo en la cinta de entrada. Cuando el AP da
un movimiento tipo 2 pasa lo siguiente:
No se consume ningún símbolo en la entrada, es como si el AP ni siquiera se fijara la cinta de
entrada y la cabeza lectora se queda estática donde estaba (es claro que si hay más de un par
de imágenes entre llaves se tiene que hacer una elección de qué par utilizar, genéricamente se
elige (qj,)); el estado actual cambia a qj; y el tope de la pila X se reemplaza por .
Por ejemplo, con la transición (q2,,X)={(q2,YX)} y la d.i. (q2,abbaa,XXZ), el siguiente
movimiento tipo 2 es posible: (q2,abbaa,XXZ) |-- (q2,abbaa,YXXZ).
Fíjese que el estado actual ‘cambia’ de q2 a q2; que se consume nada en la cadena de entrada;
que en la pila el tope X se reemplaza por YX; y lo que estaba debajo del tope (XZ en nuestro
caso) se mantiene tal cual.
Este movimiento de tipo 2 permite que el AP manipule la pila sin leer símbolos de entrada.
En cualquiera de los dos tipos de movimiento, es posible que utilicemos alguna imagen
donde =, en este caso se sustituye el tope X por , que en realidad significa que extraemos
el tope X de la pila sin introducir nada en su lugar (denominada a veces operación pop).
Por ejemplo, con la transición (q2,,X)={(q2, )} y la d.i. (q2,abb,XYZ) el siguiente
movimiento tipo 2 es posible: (q2,abb,XYZ)|--(q2,abb,YZ).
Fíjese que el estado actual ‘cambia’ de q2 a q2; que se no se consume nada en la cadena de
entrada; que en la pila el tope X se extrae; y lo que estaba debajo del tope (YZ en nuestro
caso) se mantiene tal cual.
Funcionamiento de un AP
Un AP empieza su trabajo en la d.i. inicial y empieza a dar movimientos.
Cuando ocurra que un AP termine de consumir toda su cadena de entrada, ello se denota con
como segundo elemento de una d.i. -genéricamente (qi,,)- en especial si la cadena de
entrada es la cadena vacía ello ocurre desde la d.i. inicial.
Cuando ocurra que un AP vacíe su pila, ello se denota con como tercer elemento de una d.i.
-genéricamente (qi,w,.
Es posible que ambas cosas ocurran, consumir toda la entrada y vaciar la pila, lo que se
denotará así (qi,,.
Ejemplo:
Recordemos -y enumeremos- las reglas de transición de nuestro ejemplo
(q0,a,Z)={(q0,XZ)}
2) (q0,a,X)={(q0,XX)}
3) (q0,b,X)={(q1,)}
4) (q1,b,X)={(q1,)}
5) (q1,,Z)={(q2,)}
Empecemos a describir el funcionamiento de este AP con la cadena de entrada
w=aaabbb:
66
(q0,aaabbb,) d.i. inicial
|--(q0,aabbb,X) movimiento tipo 1, por la regla 1
|--(q0,abbb,XX) movimiento tipo 1, por la regla 2
|--(q0,bbb,XXX) movimiento tipo 1, por la regla 2
|--(q1,bb,XX) movimiento tipo 1, por la regla 3
|--(q1,b,X) movimiento tipo 1, por la regla 4
|--(q1,,) movimiento tipo 1, por la regla 4 (se ha consumido toda la entrada)
|--(q2,,) movimiento tipo 2, por la regla 5 (se ha vaciado la pila)
Como sabemos, ello puede resumirse así:
(q0,aaabbb,)|--*(q2,,).
Ejemplo:
Con la regla de transición (q0,a,Z)={(q0,Z),(q1,) y con la d.i. q0,a,el AP puede dar:
--q0,, movimiento tipo 1, por el primer par de la regla (camino 1)
q0,a,
\
-- q1, movimiento tipo 1, por el segundo par de la regla (camino 2)
Este corto ejemplo es más bien simple, podemos imaginar AP’s con muchas reglas de
transición tales que para una cadena de entrada tengan muchos caminos de movimientos
alternativos.
El conjunto de todas las cadenas aceptadas por el AP se denota por T(A) y es el lenguaje
aceptado por el AP. Formalmente T(A)={uq0,u,|--*(qj,,) qjK}.
En los AP no siempre se vacía la pila para la cadena de entrada, ni tampoco se consume
siempre toda la cadena pues, siguiendo cierto camino del árbol de movimientos, es posible
que el autómata ya no puede dar ninguno, el caso extremo de esto es que el AP no pueda dar
siquiera un movimiento, en estos casos hay quienes utilizan la expresión ‘el autómata está
bloqueado’ o ‘el autómata hace crash’; también es posible que el autómata dé movimientos
repetitivos sin llegar a ninguna parte.
67
Ejemplos:
Con el AP A=({q0,q1},{a,b},{Z,X},,q0, Z,{})
(q0,a,Z)={(q0,XZ)}
(q0,a,X)={(q0,XX)}
(q0,b,X)={(q1,)}
(q1,b,X)={(q1,)}
(q1,,Z)={(q2,)}
q0,abb,--q0,bb,X--q1,b,--q2,b,
De modo que la entrada ‘abb’ no se acepta pues el APya no puede dar más movimientos y
no hay caminos alternativos.
Representación gráfica
Aunque es menos frecuente hay quienes utilizan la siguiente representación gráfica para AP’s:
Cada estado es un nodo.
Si el par (qj,)(qi,c,X) con c({}), se dibuja un arco de qi a qj etiquetado con [c,X; ]
Ejemplos:
El siguiente AP acepta T(A)={aibib / i0}
Fíjese como Z puede usarse incluso en el centro y el tope de la pila.
A=({q0,q1},{a,b},{Z},,q0,Z,{})
(q0,a,Z)={(q0,ZZ)}
(q0,b,Z)={(q1,)} Por cada a coloca Z, por cada b saca Z
(q1,b,Z)={(q1,)}
68
El siguiente AP acepta también T(A)={aibi / i>0}
Fíjese como Z sólo sirve para empezar a trabajar con el AP y luego desaparece de escena:
A=({q0,q1},{a,b},{Z,X},,q0,Z,{})
(q0,a,Z)={(q0,X)}
(q0,a,X)={(q0,XX)}
(q0,b,X)={(q1,)}
(q1,b,X)={(q1,)}
El siguiente AP acepta T(A)={ aibk+ick / i,k > 0}={ aibi+kck / i,k > 0}={ aibi bkck / i,k > 0}
(q0,,S)={(q0,WZ)}
(q0,,W)={(q0,AWB),(q0,AB)} Pre-coloca A por cada posible a
(q0,,Z)={(q0,BZC),(q0,BC)} Pre-coloca B por cada posible b
(q0,a,A) = {(q0,)} Por cada a saca A, por cada b saca B
(q0,b,B) = {(q0,)} Idem para b,c con B,C
(q0,c,C) = {(q0,)}
69
Toma de posición, necesidades y errores comunes
Ya advertimos que en ciertos casos hay que tomar posición. Algunos elementos que aquí
presentamos como errores pueden ser aceptados por otras definiciones de AP’s o por variantes
más flexibles, sin embargo, nuestra definición es muy común.
Utilizar la regla (q0,a,XZ)={(q0,Z) para que se de un movimiento si la pila tiene ‘XZ’ en el
tope, o peor, si el contenido de la pila es ‘XZ’ no está de acuerdo con nuestra definición que
sólo acepta preguntar por un símbolo en el tope y por lo tanto es un error.
Utilizar la regla (q0,a,X)={(q0,) para que se extraigan tres elementos de la pila no está
de acuerdo con nuestra definición que sólo permite extraer un símbolo de la pila, el del tope;
además es el neutro en la concatenación, luego =.
Utilizar la regla (q0,a,)={(q0,Z) para que se de un movimiento independientemente de lo
que tenga la pila en el tope, o para preguntar si la pila está vacía es un error pues nuestra
definición exige preguntar por el tope de la pila.
Más que un error es un exagerado respeto a Z el símbolo inicial de la pila, si bien un AP
empieza con sólo este símbolo en su pila, nada impide cambiarlo en el primer movimiento, o
que aparezca -más tarde- al centro o en el tope de la pila, inclusive varias veces, por ejemplo
la siguiente regla de transición es buena (q0,a,Z)={(q0,ZXXZZYY).
Aunque no lo subrayamos trabajaremos con el hecho de que ()=, otra literatura no hace
esta distinción; de igual manera hay quienes aceptan preguntar por un símbolo especial que
denota pila vacía, que no es otra cosa que consultar si la pila está vacía o notaciones
particulares tales como (qi,,)={(qj,)} en vez de X (qi,,X)={(qj,X)}.
En este como en otros casos, sin embargo, es posible -con nuestra definición- escribir AP’s de
manera que satisfagan las necesidades que se tengan, utilizando por ejemplo Z como marca de
pila “vacía”, o bien recurriendo a varios estados y/o reglas auxiliares para efectuar ciertos
movimientos complejos:
Por ejemplo, una necesidad común es, dado un símbolo b en la cinta (o bien para ignorar la
cinta) y otro X en el tope de la pila, pasar de un estado qi a otro qj extrayendo no sólo X sino
otros símbolos –digamos dos en total, no es difícil generalizar ello-. Podemos hacerlo así,
donde qa denota un estado auxiliar:
(qi,b,X)={(qa,)}
(qa,,Y)={(qj,)} si Y es el segundo símbolo a extraer, o bien
Y(qa,,Y)={(qj,)} o bien otra expresiones del tipo Y-{X}, etc.
Así las reglas (qi,b,X)={(qa,)} y (qa,,X)={(qj,)} permiten extraer dos X’s por cada b.
Otra necesidad común es extraer una X del tope de la pila por cada dos b’s, lo hacemos con
(qi,b,X)={(qa,X)} y (qa,b,X)={(qj,)}.
Otra necesidad común es añadir una X al tope de la pila por cada dos b’s, lo hacemos con
(qi,b,Y)={(qa,Y)} y (qa,b,Y)={(qj,XY}.
Otra necesidad común es añadir dos X’s al tope de la pila por cada b, lo hacemos con
(qi,b,Y)={(qa,XY)} y (qa,,X)={(qj,XX}.
Insistimos en que se trabajan dos símbolos por simplicidad y espacio, las mismas reglas dan
idea de cómo generalizar ello a más símbolos.
70
AUTÓMATAS DE PILA POR ESTADO FINAL (APe.f.)
La definición de los APe.f. es análoga a la de los AP, así como la idea de movimientos,
descripciones instantáneas, etc. La diferencia está en que el conjunto de estados finales F no
es vacío y en las condiciones bajo las cuales una cadena es aceptada.
Ejemplo:
El siguiente APe.f. A=({q0,q1,q2},{a,b},{Z,X},,q0,Z,{q2}) acepta T(A)={aibi / i>0}
(q0,a,Z)={(q0,XZ)}
(q0,a,X)={(q0,XX)}
(q0,b,X)={(q1,)}
(q1,b,X)={(q1,)}
(q1,,Z)={(q2,XXX)}
Nótese que cuando este APe.f. acepta las cadenas de entrada, la pila no se vacía.
No Determinismo
El siguiente AP acepta T(A)={ w w ~ / w{a,b}* }
A=({q0,q1},{a,b},{Z,A,B},,q0,Z,{})
(q0,a,Z)={(q0,A)}
(q0,b,Z) ={(q0,B)}
(q0,a,A)={(q0,AA),(q1,)} Por cada a coloca A, por cada b coloca B
(q0,b,B)={(q0,BB),(q1,)} Como el centro es incierto, lo adivina
(q0,a,B)={(q0,AB)} ~
a es la última letra de w o la primera de w
(q0,b,A)={(q0,BA)} Lo mismo para b
(q1,a,A)={(q1,)} Por cada a saca A, por cada b saca B
(q1,b,B)={(q1,)}
71
El siguiente AP acepta T(A)={ w{a,b}* / w es palíndrome}
A=({q0,q1},{a,b},{Z,A,B},,q0,Z,{})
(q0,,Z) ={(q1,)}
(q0,a,Z)={(q0,A),(q1,)}
(q0,b,Z) ={(q0,B),(q1,)}
(q0,a,A)={(q0,AA),(q1,A),(q1,)} Como el anterior ejemplo pero esta vez
(q0,b,B)={(q0,BB),(q1,B),(q1,)} ~
a también puede ser la letra central entre w y w
(q0,a,B)={(q0,AB),(q1,B)} Idem para b
(q0,b,A)={(q0,BA),(q1,A)}
(q1,a,A)={(q1,)}
(q1,b,B)={(q1,)}
Ejemplo:
Para L={ w{a,b}* / Na(w)>Nb(w) }
Los siguientes APe.f aceptan L
APe.f No Determinístico APe.f Determinístico
A=({q0,q1,q2,qf},{a,b},{Z,A,B},,q0,Z,{qf}) A=({q0,qf},{a,b},{Z,A,B},,q0,Z,{qf})
(q0,a,Z)={(q1,AZ)} (q0,a,Z)={(qf,Z)}
(q1,a,A)={(q1,AA)} (qf,a,Z)={(qf,AZ)}
(q1,b,A)={(q1,)} (qf,a,A)={(qf,AA)}
(q1,b,Z)={(q2,BZ)} (qf,b,A)={(qf,)}
(q1,a,Z)={(q1,AZ)} (qf,b,Z)={(q0,Z)}
(q0,b,Z)={(q2,BZ)} (q0,b,Z)={(q0,BZ)}
(q2,b,B)={(q2,BB)} (q0,b,B)={(q0,BB)}
(q2,a,B)={(q2,)} (q0,a,B)={(q0,)}
(q2,a,Z)={(q1,AZ)}
(q2,b,Z)={(q2,BZ)}
(q1,,A)={(qf,)}
72
Sin embargo, a diferencia de lo que sucede con los AF’s los AP’s No Determinísticos no son
equivalentes a los Determinísticos, es decir, hay lenguajes que son aceptados por AP No
Determinísticos para los cuales no existe ningún AP Determinístico que los acepte.
Daremos un ejemplo en la segunda parte.
73
CAPÍTULO 7. LENGUAJES SENSIBLES AL CONTEXTO
Un lenguaje es sensible al contexto si hay una Gramática Sensible al Contexto que lo genera,
o un Autómata Limitado Linealmente que lo acepte.
Ejemplos:
Sea la GSC G=({S,B,C},{a,b,c},P,S)
P:
S --> aSBC
S --> abC
CB --> BC
bB --> bb
bC --> bc
cC --> cc
L={aibici / i>0}
Intentemos una breve descripción de cómo se comporta esta GSC:
Es claro que S=>abC=>abc utilizando la segunda y la quinta producción.
Derivemos aaabbbccc utilizando las producciones pertinentes:
S=>aSBC
=>aaSBCBC
=>aaabCBCBC
... hasta aquí hemos utilizado las producciones 1 y 2 que podrían recibir el sobrenombre de
generadoras; en efecto estas dos producciones generan cadenas que tienen un número igual de
símbolos que son o representan a’s, b’s y c’s (aunque todavía no en el orden deseado, ni de
sólo Terminales). Sigamos...
=>aaabCBCBC=>aaabCBBCC=>aaabBCBCC=>aaabBBCCC
... que se obtiene utilizando varias veces la tercera producción, que reemplaza la cadena CB,
subrayada para que se note mejor, por la cadena BC, en negrita para que se note mejor, esta
producción podría recibir el sobrenombre de ordenadora.
Sigamos...
74
=>aaabbBCCC=>aaabbbCCC=>aaabbbcCC=>aaabbbccC=>aaabbbccc
... que se obtiene utilizando las últimas tres producciones, que actúan simulando una caída de
dominó y que podrían recibir el sobrenombre de minusculizadoras.
Sabemos que hay muchas otras derivaciones posibles a partir de S, un ejemplo de una
derivación alternativa es el siguiente:
S=>aSBC=>aaSBCBC=>aaabCBCBC=>aaabcBCBC=>aaabcBBCC
Que se trunca ahí.
75
El formato --> con ||||, permite conjuntos extraños de producciones.
Ejemplo:
Sea la GSC G=({S},{a,b,c,d},P,S)
P:
S --> ab
ab --> cd
L={ab,cd}
Ejemplo:
Sea la GSC G=({S,A,D,W,Y,Z,Xa},{a},P,S)
P:
S --> DS
S --> A
DA --> XaY
Y --> XaA
DXa --> XaW
W --> XaZ
Z --> XaD
A --> Xa
Xa --> a
k
L={ a3 / k0 } además G está en FNK
76
abaab abaab
^ ^
| |
Los ALL’s introducen nuevos tipos de movimientos de manera que el cabezal de la cinta de
entrada, ya no solo podrá quedarse estático, sino que -incluso- podrá ir hacia la izquierda o
hacia la derecha o quedarse fijo, según sus reglas de transición. Más aún, los ALL’s tienen la
capacidad de modificar los símbolos de la cinta de entrada; por ejemplo, en algún momento la
entrada aaba puede cambiar por aada o bien por aa&a.
77
Ninguna cuádrupla tiene como tercer componente a ni
Ninguna cuádrupla empieza con qf
Está claro pues que la cinta (de entrada) de los ALL’s es finita y está limitada por los
marcadores y .
Así, las reglas de transición de un ALL siguiendo esta representación en cuádruplas tendrían
la siguiente apariencia:
q0a R q1
q1b * qf
Obviamente este es sólo un ejemplo para mostrar la apariencia de un ALL: el número y la
forma exacta de las cuádruplas depende del lenguaje en consideración.
Si no hay dos cuádruplas que empiecen con el mismo par inicial qia . ., el ALL se dice
determinístico, en otro caso se dice no determinístico.
Ejemplos:
El ALL A=({q0,q1,qf},{a}{ }{,},,q0,{qf})
: q0aRq1
Acepta T(A)={}, pues nunca llegará al estado final -condición para aceptar cadenas-.
78
El ALL A=({q0,q1,q2,q3,q4,q5,qf},{a,b}{*,&}{,},,q0,{qf})
:
1) q0a * q4
2) q4 R q1
3) q1a R q1
4) q1& R q1
5) q1b & q5 La idea es marcar una a con *
6) q5& L q2 e ir a la derecha a marcar una b con &
7) q2& L q2 volver a la izquierda a hacer lo mismo nuevamente
8) q2a L q2
9) q2* R q0
10) q0& R q3
11) q3 R q3
12) q3 L qf
Acepta T(A)={aibi / i>0}, presentaremos los movimientos para la aceptación de la cadena
“aabb” indicando con un subíndice el número de regla utilizado:
(1,q0,aabb)|--1(1,q4,*abb)|--2(2,q1,*abb)|--3(3,q1,*abb)|--5(3,q5,*a&b)
|--6(2,q2,*a&b)|--8(1,q2,*a&b)|--9(2,q0,*a&b)|--1(2,q4,**&b)
|--2(3,q1,**&b)|--4(4,q1,**&b)|--5(4,q5,**&&)|--6(3,q2,**&&)
|--8(2,q2,**&&)|--9(3,q0,**&&)|--10(4,q3,**&&)|--11(5,q3,**&&)
|--12(4,qf,**&&), es decir,
(1,q0,aabb)|--*(4,qf,**&&)
El ALL A=({q0,q1,q2,q3,q4,q5,qf},{a,b}{*,&}{,},,q0,{qf})
δ:
q1 L qf Para la cadena vacia
79
qi $ L qi Va a la izquierda hasta encontrar ‘*’ (salta las marcas $)
qi a L qi
qi a L qi
qi * R qu qu(q uno) representa “volver a empezar”
80
SEGUNDA PARTE
81
CAPÍTULO 8. TÓPICOS SOBRE LENGUAJES REGULARES
Propiedades de L/u:
1) Si L1 L2 entonces L1/u L2/u
2) (L1 L2)/u = L1/u L2/u
3) (L1 L2)/u = L1/u L2/u
4) (L1L2)/a = (L1/a)L2 si L1
(L1L2)/a = (L1/a)L2 L2/a en otro caso
5) L*/a = (L/a)L*
6) L/uw = (L/u)/w
El cociente izquierdo de L1 entre L2, denotado por L1/L2 es:
L1/L2 = { w / uw L1, u L2 }
82
¿L=L(G)?
Si se tiene
a) una gramática y se sugiere un lenguaje L como el lenguaje que genera la gramática; o
b) un lenguaje L y se construye el conjunto de producciones pensadas para generar L
y el observador cae en cuenta de que existe una clara equivocación, es decir que L L(G), es
decir que esas producciones no generan el lenguaje que se indica en L, entonces en este caso
bastará la derivación de una cadena que no esté en L a través de las producciones, a manera de
contraejemplo.
Ejemplo:
Dada la GR G=({S},{a,b},P,S)
P:
S --> Sa | Sb | a
L={(ab)i / i > 0}
Basta con la derivación S => a (por la tercera producción) para mostrar una cadena que sí está
en L(G) y que no está en L pues para ningún i sucede que a=(ab)i, esto es suficiente para
comprobar que L L(G).
En otras palabras
a) si las producciones estaban dadas y se pedía indicar el lenguaje que generan, dicho L está
errado; o
b) si L estaba dado y se pedía construir las producciones de una GRLI, tales producciones no
generan L.
Sin embargo, si parece que en efecto el lenguaje que genera la gramática L(G) es el mismo
que el lenguaje L, entonces dicho parecer debe transformarse en seguridad a través de una
demostración.
Si bien esta es una salida genérica, las demostraciones son largas y quizás áridas.
Ejemplos:
Sea la GRLI G=({S}, {a}, P, S)
P:
S --> Sa
S --> a
Sugerimos que el lenguaje que genera G es L={ai / i > 0}. Y demostraremos que L=L(G).
83
i) L L(G)
Sea u L entonces -debemos demostrar que- u L(G).
Para las cadenas que tienen la forma sugerida en L, debemos demostrar que dichas cadenas se
derivan a partir de S en G.
Por inducción sobre la longitud de las cadenas en L.
Es claro que las cadenas en L tienen, genéricamente, una longitud |u|=i, i > 0.
Caso base:
La cadena más pequeña en L tiene longitud |u|=1, cuando dicha cadena es u=a, para i=1.
La derivación S => a (por 2), es lícita y muestra que u L(G)
Hipótesis inductiva:
Toda cadena u L de longitud |u|=i –dicha cadena no es otra que u=ai-, sí se puede derivar de
S en G (S=>*u), es decir, también está en L(G), o lo que es lo mismo u L(G).
Paso inductivo:
Sea una cadena w L de longitud |w|=i+1, es decir w=ai+1=ua donde |u|=i, u=ai
La siguiente derivación es lícita.
S => Sa por 1
=>* ua por hipótesis inductiva pues S=>*u, cuando u=ai, es decir, cuando u L y |u|=i
Luego S=>*w, lo que muestra que w L(G).
ii) L(G) L
Sea u L(G) entonces -debemos demostrar que- u L.
Para las cadenas que se derivan a partir de S en G, debemos demostrar que dichas cadenas
tienen la forma indicada en L.
Por inducción sobre el número de pasos de derivación de una cadena en L(G).
Caso base:
Sea u L(G) que se deriva en el menor número de pasos de derivación, es decir un paso. La
única cadena que se puede derivar de S en un solo paso, con la derivación S => a (por 2), es
u=a.
Ahora u=a=a1=ai con i=1, que obviamente obedece el formato de L, es decir, u L.
Hipótesis inductiva:
Toda cadena u L(G) que se deriva de S en k pasos o menos también está en L, o lo que es lo
mismo u L.
Paso inductivo:
Sea w L(G) que se deriva de S en k+1 pasos.
Para dar k+1 pasos de derivación primero damos un paso de derivación y luego los restantes
k pasos, desglosemos pues de este modo los k+1 pasos de derivación de w.
S => cadenauno aquí está el primer paso de derivación
=>* w a partir de cadenauno se dan otros k pasos de derivación para obtener w
haciendo un total de k+1 pasos de derivación
84
Ahora bien por la forma de las producciones de G, en el primer paso de derivación a partir de
S, la cadena resultante (cadenauno) no puede ser otra que Sa utilizando la primera producción
(pues la otra alternativa es utilizar la producción 2 que nos devuelve al caso base y que deja
los restantes k pasos iguales a cero).
Luego la derivación de w a partir de S en k+1 pasos no debe ser otra que
S => Sa por 1, primer paso de derivación
=>* w w se obtiene de Sa con los siguientes k pasos de derivación
Pero entonces, por hipótesis inductiva u L, puesto que se deriva de S en k pasos, es decir,
u=ai (i>0), de donde w=aia. Es decir, w=ai+1, o lo que es lo mismo w=aj, con j=i+1 (j > 0).
Luego, w L.
Sea la GRLD G=({S,B}, {a,b}, P={ S --> aB, B --> bS, B --> b}, S)
Sugerimos que el lenguaje que genera G es L={(ab)i / i > 0}.
Y demostraremos que L=L(G).
85
i) L L(G)
Sea u L entonces -debemos demostrar que- u L(G).
Para las cadenas que tienen la forma sugerida en L, debemos demostrar que dichas cadenas se
derivan a partir de S en G.
Por inducción sobre la longitud de las cadenas en L.
Es claro que las cadenas en L tienen, genéricamente, una longitud |u|=2i, i > 0.
Caso base:
La cadena más pequeña en L tiene longitud |u|=2, cuando dicha cadena es u=ab, para i=1
La derivación
S => aB por 1
=> ab por 3
es lícita y muestra que u L(G)
Hipótesis inductiva:
Toda cadena u L de longitud |u|=2i –dicha cadena no es otra que u=(ab)i-, sí se puede
derivar de S en G (S=>*u), es decir, también está en L(G), o lo que es lo mismo u L(G).
Paso inductivo:
Sea wL de longitud |w|=2(i+1)=2i+2, es decir w = (ab)i+1 = abu donde |u|=2i, u=(ab)i
La siguiente derivación es lícita.
S => aB por 1
=> abS por 2
=>*abu por hipótesis inductiva
pues S=>*u, cuando u=(ab)i, esto es, cuando u L y |u|=2i, que es el caso
Luego S=> w, lo que muestra que w L(G)
*
ii) L(G) L
Sea u L(G) entonces -debemos demostrar que- u L.
Para las cadenas que se derivan a partir de S en G, debemos demostrar que dichas cadenas
tienen la forma indicada en L.
Por inducción sobre el número de pasos de derivación de una cadena en L(G).
Caso base:
Sea u L(G) que se deriva en el menor número de pasos de derivación, en el caso que nos
ocupa dos pasos. La única cadena que se puede derivar de S en dos pasos, con la derivación
S=>aB=>ab -por 1 y 3 respectivamente- es u=ab.
Ahora u=ab=(ab)1=(ab)i con i=1, que obviamente obedece el formato de L, es decir, u L.
Hipótesis inductiva:
Toda cadena u L(G) que se deriva de S en menos de k pasos también está en L, o lo que es
lo mismo u L.
Paso inductivo:
Sea w L(G) que se deriva de S en k pasos.
86
Vamos a desglosar estos k pasos de derivación de la siguiente manera, notando que para el
primer paso de derivación la única producción utilizable es la primera.
S => aB aquí está el primer paso de derivación, por 1
=> abS por 2
la otra alternativa para este segundo paso de derivación es usar la producción 3
lo que nos devuelve al caso base ya visto
=>*abu los restantes pasos (del total de k pasos) para obtener w
Aunque la literatura rara vez demuestre la comprobación del lenguaje generado para una
gramática completa, es importante comprender la significación del razonamiento expuesto: la
comprobación de que un conjunto dado de producciones genera un lenguaje determinado;
pues de lo contrario la teoría tendría poco que ofrecer y nosotros mucho que confiar -a ciegas-
en lo que los proponentes de L’s o de producciones hagan.
Las ideas aquí presentadas no sólo sirven para gramáticas regulares sino que pueden aplicarse
a otro tipo de gramáticas.
Ella da cuenta de la validez de (q1,) |--* (q1,) y de nuestra regla práctica: si el estado inicial
es un estado final entonces T(A) donde A es un AFD.
87
b) |xy| n
c) y la subcadena y no es vacía
d) i0 xyiz T(A)
Demostración:
Sabemos que si se presenta u como entrada al AFD, u=a1a2...am con m n, este termina en un
estado final. Graficaremos la lista de estados que visita el AFD al consumir u empezando en
el estado inicial así:
Esta gráfica no es el diagrama de transición del AFD sino un dibujo de los estados por los que
vamos transitando al consumir la cadena u, para hacer notar la diferencia más aún hemos
dibujado los estados en cuadrados en vez de círculos.
Ejemplo:
Para el AFD A=({q1q2},{b},,q1,{q2})
:
q1b)=q2
q2b)=q1
con la cadena u=bbbbb la lista de estados que visita el AFD -incluyendo el estado inicial- al
consumir u es q1,q2,q1,q2,q1,q2, gráficamente ello se ve así:
Donde se evidencia que por lo menos un estado se visita más de una vez -cuando menos dos
veces- adicionalmente nótese que con 5 símbolos se visitan 6 estados.
Volviendo al caso general, dado que u consiste de por lo menos n símbolos podemos
reescribir esta cadena así u=a1a2...anan+1...am con m n, o lo que es lo mismo u=a1a2...anz con z
la subcadena final; al transitar -desde el estado inicial- a través de los estados del AFD
consumiendo los símbolos de u (los primeros n símbolos y luego los símbolos de z) la lista de
estados que visita el AFD tendrá por lo menos n+1 estados. Sabiendo esto se deduce que no
es posible que en esta lista de estados que se visita todos estos estados sean distintos, puesto
que sólo existen n estados diferentes. Luego debe existir por lo menos un estado que se visita
más de una vez.
Visto de otro modo -en la gráfica de la lista de estados que se visita – por lo menos algún j es
necesariamente igual a algún k, este hecho suele mostrarse así evidenciando el ciclo:
88
Es decir, con la cadena u la lista de estados que se visita es q1,qi1,qi2,...,qr,...,qr,...qf, donde el
estado que se repite es qr (que es igual a qj y a qk)
Podemos escribir esto así:
q1,x)=qr donde x contiene los primeros símbolos de u que me permiten llegar a qr
qr,y)=qr donde y contiene los siguientes símbolos de u que me permiten revisitar qr
qr,z)=qf donde z contiene los últimos símbolos de u con los que llegamos a qf
y pues hemos admitido que hay por lo menos un estado que se visita por lo menos dos
veces, con y= no habría tal re-visita.
Nótese que la subcadena y está en un ciclo que puede repetirse 0, 1, 2 o más veces con la
propiedad siguiente qr,yi)=qr; de este modo si luego de la subcadena x, y luego de una o
más y’s está la subcadena z, toda la cadena resultante sigue llegando finalmente a qf, es decir,
las cadenas del tipo xyiz T(A) para todo i 0.
Ya vimos que u puede reescribirse así u=a1a2...anz, y que a1a2...an puede agruparse en dos
subcadenas xy; es decir, efectivamente u puede reescribirse así u=xyz. Sin embargo, la parte
vital del lema es que por lo menos un estado se visite cuando menos dos veces, ello sucede
inevitablemente si xy=a1a2...an pues –como se argumentó- con n símbolos se visitan n+1
estados. Es claro que esta vital revista puede suceder con menos símbolos aún como lo
muestra el siguiente ejemplo: sea A=({q1q2q3q4q5},{a,b},,q1,{q1}) n=|K|=5
: q1a)=q1 q1b)=q2 q5a)=q5b)=q1 qja)=qjb)=qj+1 j=2,3,4
Sea u=aaaaaa, la lista de estados que se visita es: q1,q1,q1,q1,q1,q1,q1 donde la revisita es
evidente. Aquí x=a, y=a, z=aaaa lo que es válido, nótese que |xy|=2<5; pero también puede ser
x=aa, y=a, z=aaa lo que es igualmente válido, nótese que |xy|=3<5; o bien x=, y=aaa, z=aaa
lo que es igualmente válido, nótese que |xy|=3<5. En todos estos casos |xy|n, es decir, u
puede reescribirse así u=xyz con |xy|n.
El teorema de Myhill-Nerode
Una relación R de equivalencia definida sobre Σ∗ divide Σ∗ en clases, es decir,
Σ∗ = [x1] ∪ [x2] ∪ . . . ∪ [xk] ∪ . . .
Donde [xi] representa la clase de xi.
La intersección de dos clases es vacía, es decir, [xi] ∩ [xj] = ∅ si i ≠ j
Ejemplos:
Sea Σ = {a1 , . . . , ak} un alfabeto. Definamos la relación R sobre Σ∗ así
R = {(x, y) | x comienza con el mismo símbolo que y}
R es una relación de equivalencia y particiona Σ∗ así:
Σ∗ = [a1] ∪ [a2] ∪ . . . ∪ [ak] ∪ [λ]
Es decir, en todas las clases de palabras que empiezan con la misma letra más la clase para la
palabra vacía (que no empieza con ninguna letra).
Indice(R) = k + 1 = |Σ| + 1. Es decir, R tiene índice finito.
89
Definamos la relación R sobre Σ∗ así:
R = {(x, y) / x tiene la misma longitud que y}
R es de índice infinito.
RL es también conocida como relación de equivalencia para los buenos finales inducida por L
y también como Relación de Indistinguibilidad.
Si xRLy se dice que x es indistinguible de y.
En cambio si x no está RL relacionada con y se dice que x,y son distinguibles. De hecho,
existe una cadena w que las distingue: w es tal que xwL pero ywL, o bien xwL pero
ywL.
Ejemplos:
Sea = {a,b,c}. Sea L={aibj / i,j ≥ 0}
La relación RL tiene índice finito, Indice(RL) = 3. Las clases son:
[]RL = {, a, aa, …} cadenas de sólo a’s o
[ba]RL = {ba, baa, bab, …, c, acb,…} cadenas que incluyen ‘ba’ o ‘c’
[b]RL = {b, bb, bbb, …} todas las otras cadenas
Sea = {a,b}. Sea L={uv / |u|=|v| ^ u,v {a,b}* ^ v contiene una ‘b’}
La relación RL tiene índice infinito.
Cualquier par de cadenas x=ajb, y=akb (j<k; j,k impar) se distinguen con w=ak-1.
Cada una de esas infinitas cadenas pertenece a una clase diferente: hay infinitas clases.
90
Una relación R sobre se dice que es invariante por derecha con respecto a la concatenación
si z: xRy => xzRyz
La relación RL es además invariante por la derecha. En efecto, sea que xRLy, es decir,
v xv L yv L; debemos mostrar que z xzRLyz, es decir, que
z,w xzw L yzw L; hagamos v=zw, luego debemos mostrar que
z,w (v=zw) xv L yv L, pero eso es precisamente lo que significa xRLy.
El teorema de Myhill-Nerode dice que los tres enunciados siguientes son equivalentes:
1) L=T(A), donde A es un AFD
2) L es la unión de algunas clases de equivalencia de alguna relación de equivalencia R
definida sobre , invariante por derecha y de índice finito.
3) RL es de índice finito.
Demostración:
1) => 2)
Sea A un AFD tal que T(A)=L, entonces vamos a mostrar que hay una relación de
equivalencia definida sobre , invariante por derecha y de índice finito.
Definamos pues la relación a la que llamaremos RA:
xRAy si y sólo si q1,x)=q1,y)
Es evidente que RA es de equivalencia pues:
a) q1,x)=q1,x), es decir RA es reflexiva
b) q1,x)=q1,y) => q1,y)=q1,x), es decir RA es simétrica
c) [q1,x)=q1,y) q1,y)=q1,z)]=> q1,x)=q1,z), es decir RA es transitiva
También RA es invariante por derecha pues:
Si xRAy se sabe que q1,x)=q1,y).
Además z q1,xz)=*(*(q1,x),z) por un resultado previo
=*(*(q1,y),z) pues q1,x)=q1,y)
=q1,yz) por el resultado previo
Es decir, z q1,xz)= q1,yz), que no es otra cosa que decir que xzRAyz
91
Es evidente que L es la unión de las clases de RA que han sido formadas de manera tal que sus
cadenas llegan a los estados finales del AFD.
2) => 3)
Sea L la unión de algunas clases de alguna relación de equivalencia R definida sobre ,
invariante por derecha y de índice finito, entonces vamos a mostrar que RL también es de
índice finito.
En efecto, sean x,y tales que
xRy, es decir, (x,y)R, es decir, x e y están relacionadas y están en la misma clase de
equivalencia digamos [x]R, pero entonces
z xzRyz pues R es invariante por derecha, además
z xzL si y sólo si yzL
pues L es la unión de algunas clases de R, es decir,
si (xz,yz)R, o lo que es lo mismo, si están en la
misma clase y dicha clase aporta a conformar L,
ambas cadenas xz y yz están en L, en otro caso no;
pero entonces
xRLy pues la expresión xzL si y sólo si yzL, no es sino la definición de RL, es
decir, (x,y)RLes decir, x y y están relacionados por RL y están en la misma clase
de equivalencia digamos [x]RL.
Así, hemos mostrado –tomando de a dos los elementos- que si hay cadenas que están en una
misma clase en R, esas cadenas también están en una misma clase en RL, es decir, [x]R[x]RL,
otra manera de decirlo es que cada clase de equivalencia de R está contenida en alguna de RL
(en estos casos se dice que R refina a RL), es claro a partir de ello que R tiene más clases –o las
mismas- que RL, es decir, R tiene un índice mayor o igual que el índice de RL y como el índice
de R es finito, RL también tiene un índice finito.
3) => 1)
Sea RL -de índice finito-, entonces vamos a mostrar que hay un AFD A tal que T(A)=L
En efecto, construimos así el AFD A=(K,,,q1,F)
K es el conjunto de clases de equivalencia de RL
K={[x]RL / x}
q1=[]RL el estado inicial es la clase de equivalencia de (que incluye a) la cadena vacía
F={[x]RL / xL}
: ([x]RL,a)=[xa]RL
Sólo resta mostrar dos cosas: a) que tanto el conjunto de estados como la regla de transición
son consistentes, es decir, que están acordes a la definición de un AFD y no traen problemas;
y b) que este AFD acepta L.
a) K es finito pues RL es de índice finito.
En la clase de equivalencia de la cadena x, [x]RL, hay posiblemente otras cadenas por ejemplo
y, dado que están en la misma clase xRLy, y también [x]RL=[y]RL. Según nuestra regla de
transición ([y]RL,a)=[ya]RL, sería inconsistente que [xa]RL[ya]RL.
92
Afortunadamente eso no sucede [xa]RL[ya]RL, pues RL es invariante por la derecha, es decir,
z por ejemplo z=a, si xRLy entonces xaRLya, es decir, xa y ya están en la misma clase
de equivalencia, es decir, [xa]RL[ya]RL.
b) Utilizaremos el hecho de que (q1,x)=[x]RL
En efecto cuando x= tenemos que (q1,x)=(q1,)=q1=[]RL=[x]RL
Y cuando x=ya tenemos que (q1,x)=(q1,ya)=((q1,y),a)=([y]RL,a)=[ya]RL=[x]RL
Finalmente, xT(A) si y sólo si (q1,x)F si y sólo si [x]RLF si y sólo si xL, es decir el
AFD acepta L.
B0 = C
Bi+1 = Bi d(q,
q Bi
i=0,1,... (*)
Que este algoritmo sea finito es evidente: a partir de C pueden añadirse uno o más estados de
manera que algún Bi+1 sea K en el extremo, a partir de ahí Bi+2 y los siguientes deben ser
iguales al anterior pues ya no hay más estados que añadir.
Si Bi+1 = Bi Entonces n>0 Bi = Bi+n,
Demostración:
Por inducción sobre n:
Caso base.
n=1
Si Bi+1 = Bi entonces Bi = Bi+1 es verdadero inmediatamente.
Hipótesis inductiva.
n=k
Si Bi+1 = Bi entonces Bi = Bi+k es cierto.
Paso inductivo.
n=k+1
Sea Bi+1 = Bi (**)
Luego,
Bi = Bi+1 por (**)
= Bi d(q,
q Bi
por la forma de calcular cada Bi+1 en el cálculo del -cierre(C) (*)
= Bi+k d(q,
q Bi+k
por hipótesis inductiva
= Bi+k+1 por la forma de calcular cada Bi+1 en el cálculo del -cierre(C) (*)
Por los tres casos el enunciado que queríamos demostrar es cierto.
93
Cómo demostrar las equivalencia entre expresiones regulares
Existen varias equivalencias muy conocidas:
Grupo I Grupo II Grupo III
(r+s) (s+r) r r r r(s+t) rs+rt
(r+s)+t r+(s+t) r r (s+t)r sr+tr
r+s+t (rs)t r(st) rst
r+ +r r
r+r r
Grupo IV Grupo V Grupo VI
r* r*r* (r+s)* (r*+s*)*
(r*)* r* +rr* (r*s*)* (r*s)*r*
(+r) *
r*(sr*)*
* * pero
(r+s)* r*+s*
*
Grupo VII Grupo VIII
r r rr
* *
(r s) +(r+s) s
* * *
94
En todo caso la idea de simplificación suele partir de una e.r. larga y tratar de obtener una e.r.
mucho más corta.
Sin apelar a autómatas, los grupos de equivalencias utilizadas pueden demostrarse de dos
formas:
i) Las más complejas a partir de las más simples.
Ejemplo (donde subrayamos la parte de la e.r. tomada en cuenta al aplicar una equivalencia):
Si r s*t demostrar que r sr+t
r s*t Por hipótesis
(+ss )t
*
Grupo V: r*+rr*
t+ss t
*
Grupo III: (s+t)rsr+tr
t+ss t
*
Grupo II: rr
t+sr Por hipótesis s*tr
sr+t Grupo I: (r+s)(s+r)
ii) Las más simples a través de lo que se llama reasociación y/o el trabajo con lenguajes.
Ejemplos:
ii.a: Demostrar que r(sr)* (rs)*r
Es decir, demostrar que L(r(sr)*) = L((rs)*r)
Como es habitual en conjuntos, se hace en dos partes:
L(r(sr)*) L((rs)*r)
Sea w L(r(sr)*), entonces w es de la forma w=r0(s1r1)(s2r2)...(snrn) para algún n0 -cada ri y
cada sj es una (sub)cadena-, pero esta cadena w puede reagruparse o reasociarse –por la
asociatividad de la concatenación de cadenas- de esta forma: w=(r0s1)(r1s2)(r2s3)...(rn-1sn-1)rn,
por lo tanto, w L((rs)*r)
L((rs)*r) L(r(sr)*)
Sea w L((rs)*r), entonces w es de la forma w=(r0s0)(r1s1)(r2s2)...(rn-1sn-1)rn para algún n0
–cada ri y cada sj es una (sub)cadena-, pero esta cadena w puede reagruparse o reasociarse
–por la asociatividad de la concatenación de cadenas- de esta forma: w=r0(s0r1)(s1r2)...(sn-1rn),
por lo tanto, w L(r(sr)*).
ii.b: Demostrar que r* (r*)*
Es decir, demostrar que L(r*) = L((r*)*)
Sea L(r)=L, entonces lo que hay que demostrar es L* = (L*)*
Por definición de la operación * con lenguajes (L*)* = {} L* ... etc., es decir, L* (L*)*
Nos resta probar que (L*)* L*
Sea w (L*)*, es decir, por definición de la operación *, existe n tal que w (L*)n, luego w se
puede reescribir así w=w1w2...wn donde cada wi L*, además y otra vez por definición de la
operación *, para cada i existe mi tal que wi Lmi de manera que wi= wi1wi2...wi(mi) donde
cada wij L, pero entonces w Lm1+...+mn, es decir, w L*.
ii.c: Demostrar que (r+s)* (r*s*)*
Es decir, demostrar que L((r+s)*) = L((r*s*)*)
Por un lado sabemos que
95
L((r+s)*) = {} L(r+s) (L(r+s))2 ... = {} L(r+s) L(r+s)L(r+s) ...
= {} L(r) L(s) (L(r))2 (L(s))2 L(r)L(s) L(s)L(r) ...
Por otro lado también sabemos que
L((r*s*)*) = {} L((r*s*)) (L((r*s*)))2 ... = {} L((r*s*)) L((r*s*))L((r*s*)) ...
= {} L(r*)L(s*) L(r*)L(s*)L(r*)L(s*) ...
= {} L(r) L(s) (L(r))2 (L(s))2 L(r)L(s) L(s)L(r) ...
Que son iguales.
96
El último caso de la derivada respecto de un símbolo es para la e.r. r*.
Sea L=L(r), se sabe que L(r*)=[L(r)]*=L*={} L L2 L3 ...
={} L LL LLL ...
La derivada Da(r ) no es otra cosa que la e.r. que denota al lenguaje L*/a, que no es otra cosa
*
que el conjunto de cadenas en L* que empiezan con el prefijo ‘a’ y a las que se les quita dicho
prefijo.
Suprimamos pues dicho símbolo a estas cadenas, volvemos a considerar dos casos.
Cuando L(r) y sabiendo que {}/a={}, el resultado es
L*/a = {} L/a (L/a)L (L/a)LL ... = (L/a) ({} L LL ...)
= (L/a)(L*)
que puede ser denotado por Da(r)r*
Algunos denominan derivada de orden superior cuando la derivación de una e.r. se extiende a
más de un símbolo y se hace respecto de una cadena, cuya interpretación ya dimos.
Ejemplo:
Dc(c)=
Da(ac)=Da(a)c=c=c
Db(bac)=Db(b)ac=ac=ac
Dbac(bac)=Dc(Da(Db(bac)))=Dc(Da(ac))=Dc(c)=
Así cuando u=bac, Du(bac)=
Fíjese que para calcular Du(r) la secuencia de las derivadas respecto de un símbolo
corresponde a los símbolos de u leídos de izquierda a derecha.
Si definimos D(r)=r, una definición recursiva para la derivada respecto de una cadena es:
D(r)=r
Dwa(r)=Da(Dw(r))
97
Da()=
Da()=
Da(a)=
Db(a)= ab
Da(r+s)=Da(r) + Da(s)
Da(rs)=Da(r)s si L(r) o bien Da(rs)=Da(r)s + (r)Da(s) con (r)= si L(r)
Da(rs)=Da(r)s + Da(s) si L(r) (r)= si L(r)
Da(r*)=Da(r)r*
D(r)=r
Dwa(r)=Da(Dw(r))
Ejemplo:
Sea r=b(ab)*+bb*aa*, calcular Dbaa(r)
Dbaa(r)=Dbaa(b(ab)*+bb*aa*)=Da(Da(Db(b(ab)*+bb*aa*)))
Necesitamos calcular Db(b(ab)*+bb*aa*)=Db(b(ab)*) + Db(bb*aa*)
Db(b(ab)*)=Db(b)(ab)* pues L(b) no incluye a
=(ab)*=(ab)*
Db(bb*aa*)=Db(b)b*aa* pues L(b) no incluye a
=b*aa*=b*aa*
Así pues Db(b(ab)*+bb*aa*)=(ab)*+b*aa*
=b*aa*+a*=a*
Así pues Da(Db(b(ab)*+bb*aa*))=b(ab)*+a*
Finalmente
Da(Da(Db(b(ab)*+bb*aa*)))=Da(b(ab)*+a*)
=Da(b(ab)*)+Da(a*)
=Da(b)(ab)*+Da(a)a*
=(ab)* +a*
=a*
Así, Dbaa(b(ab) +bb aa )=a*
* * *
98
I. Probaremos por inducción sobre |w| que si |w|>0
Dw(s+t)=Dw(s) + Dw(t)
Caso base:
|w|=1, es decir, w=a lo que se reduce a la regla ya presentada.
Hipótesis inductiva:
El resultado sigue para cadenas w de longitud |w|=k.
Paso inductivo:
Sea w una cadena tal que |w|=k+1, es decir, podemos reescribir w así: w=ua con |u|=k. Luego,
Dw(s+t)=Dua(s+t) pues w=ua
=Da(Du(s+t)) por la regla para cadenas
=Da(Du(s) + Du(t)) por hipótesis inductiva
=Da(Du(s)) + Da(Du(t)) por la regla + ya vista, dado que Du(t) y Du(s) son e.r.
=Dua(s) + Dua(t) por la regla para cadenas
=Dw(s) + Dw(t) pues w=ua
Caso base:
|v|=0, es decir, v=
Duv(r)=Du(r) pues v=
=D(Du(r)) por la regla para cadenas
=Dv(Du(r)) pues v=
Hipótesis inductiva:
El resultado sigue para cadenas v de longitud |v|=k.
Paso inductivo:
Sea v una cadena tal que |v|=k+1, es decir, podemos reescribir v así: v=wa con |w|=k. Luego,
Duv(r)=Duwa(r) pues v= wa
=Da[Duw(r)] por la regla para cadenas
=Da[Dw(Du(r))] por hipótesis inductiva
=Dwa(Du(r)) por la regla para cadenas dado que Du(r) es una e.r.
=Dv(Du(r)) pues v= wa
III. Sea la función definida en la regla para la derivación de dos e.r. concatenadas, entonces
Dv[(s)Dw(t)] = (s)Dv[Dw(t)]
En efecto, sabemos que (s)= o bien (s)=, luego por las propiedades de las e.r.:
En el primer caso Dv[(s)Dw(t)]=Dv[Dw(t)]=Dv[]==Dv[Dw(t)]=(s)Dv[Dw(t)]
Y en el segundo Dv[(s)Dw(t)]=Dv[Dw(t)]=Dv[Dw(t)]=Dv[Dw(t)]=(s)Dv[Dw(t)]
99
Adicionalmente mostraremos por inducción sobre el número n de sumandos que
Dv{[(Du1(t))+...+(Dun(t))] Dw(t)} = [(Du1(t))+...+(Dun(t))] Dv[Dw(t)]
Caso base:
n=1, Dv{(Du1(t))Dw(t)} se reduce al resultado anterior con s=Du1(t)
Hipótesis inductiva:
El resultado sigue para k sumandos.
Paso inductivo:
Dv{[(Du1(t))+... +(Duk(t))+(Duk+1(t))]Dw(t)}
=Dv{[(Du1(t))+...+(Duk(t))]Dw(t) + (Duk+1(t))Dw(t)} distribuyendo Dw(t)
=Dv{[(Du1(t))+...+(Duk(t))]Dw(t)} + Dv{(Duk+1(t))Dw(t)} por I
=Dv{[(Du1(t))+...+(Duk(t))]Dw(t)} + (Duk+1(t))Dv[Dw(t)] por el caso base
=[(Du1(t))+...+(Duk(t))]Dv[Dw(t)] + (Duk+1(t))Dv[Dw(t)] por hipótesis inductiva
={[(Du1(t))+...+(Duk(t))] + (Duk+1(t))} Dv[Dw(t)] por la regla de distribución (grupo III)
IV. Mostraremos ahora por inducción sobre |w| que si |w|>0, w=a1a2…an
n
Dw(st) = Dw(s)t +
i 2
[Da1...a(i-1)(s)) Dai...an(t)] + (s)Dw(t)
Caso base:
|w|=1, se reduce a la regla ya presentada con la sumatoria ignorada por vacuidad.
Sólo por claridad haremos el caso cuando |w|=2, es decir, w=a1a2 (n=2).
Dw(st)=Da1a2(st) pues w=a1a2
=Da2(Da1(st)) por la regla para cadenas
=Da2(Da1(s)t+(s)Da1(t)) por la regla para concatenación
=Da2(Da1(s)t) + Da2((s)Da1(t)) por la regla + ya vista
=Da2(Da1(s))t+[Da1(s)] Da2(t) + Da2((s)Da1(t)) por la regla para concatenación
=Da2(Da1(s))t+[Da1(s)] Da2(t) + (s)Da2(Da1(t)) por III
=Da1a2(s)t+[Da1(s)] Da2(t)+(s)Da1a2(t) por la regla para cadenas
=Dw(s)t+(Da1(s)) Da2(t)+(s)Dw(t) pues w=a1a2
n
=Dw(s)t+
i 2
[Da1...a(i-1)(s)) Dai...an(t)]+(s)Dw(t) reescribiendo
Hipótesis inductiva:
El resultado sigue para cadenas w de longitud |w|=k.
Paso inductivo:
Sea w una cadena tal que |w|=k+1, es decir, podemos reescribir w así: w=uak+1 con |u|=k,
u=a1a2…ak. Luego,
100
Dw(st)=Dua(k+1)(st) pues w=uak+1
=Da(k+1)[Du(st)] por la regla para cadenas
k
=Da(k+1)[Du(s)t + i 2
[Da1...a(i-1)(s)) Dai...ak(t)] + (s)Du(t)] por hipótesis inductiva
k
=Da(k+1)[Du(s)t] + Da(k+1)[ i 2
[Da1...a(i-1)(s)) Dai...ak(t)]] + Da(k+1)[(s)Du(t)] regla +
Ahora bien
Da(k+1)[Du(s)t]
=Da(k+1)[Du(s)]t+(Du(s))Da(k+1)(t)
=Dua(k+1)(s)t+(Du(s))Da(k+1)(t)
=Dw(s)t+(Du(s))Da(k+1)(t)
por la regla para la concatenación, la regla para cadenas y dado que w=uak+1
También
Da(k+1)[(s)Du(t)]
=(s)Da(k+1)[Du(t)]
=(s)Dua(k+1)(t)
=(s)Dw(t) por III, la regla para cadenas y dado que w=uak+1.
Y también
k
Da(k+1)[
i 2
[Da1...a(i-1)(s)) Dai...ak(t)]]
k
=
i 2
[Da1...a(i-1)(s)) Da(k+1)[Dai...ak(t)]]
k
=
i 2
[Da1...a(i-1)(s)) Dai...aka(k+1)(t)] por la regla para +, III y la regla para cadenas.
Es decir,
Dw(st)
k
=Dw(s)t+(Du(s))Da(k+1)(t) +
i 2
[Da1...a(i-1)(s)) Dai...aka(k+1)(t)]+(s)Dw(t)
k
=Dw(s)t+(Da1...ak(s))Da(k+1)(t) +
i 2
[Da1...a(i-1)(s)) Dai...aka(k+1)(t)]+(s)Dw(t) pues u=a1a2…ak
k 1
=Dw(s)t+ i 2
[Da1...a(i-1)(s)) Dai...aka(k+1)(t)]+(s)Dw(t)
101
n
*
Dw(t )={ Dw(t) +
[ D u1 ( t)]... [ D u m ( t)] D a i ...a n ( t)
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
}t*
Caso base:
|w|=1, se reduce a la regla ya presentada con la sumatoria ignorada por vacuidad.
Sólo por claridad haremos el caso cuando |w|=2, es decir, w=a1a2 (n=2).
Dw(t*)=Da1a2(t*) pues w=a1a2
=Da2(Da1(t*)) por la regla para cadenas
=Da2(Da1(t) t*) por la regla para *
=Da2[Da1(t)] t* + [Da1(t)] Da2(t*) por la regla para la concatenación
=Da1a2(t) t* + [Da1(t)] Da2(t*) por la regla para cadenas
=Da1a2(t) t* + [Da1(t)] Da2(t) t* por la regla para *
={Dw(t) + [Da1(t)] Da2(t)} t* por distribución y w=a1a2
que tiene la forma de nuestro enunciado con n=2
Hipótesis inductiva:
El resultado sigue para cadenas w de longitud |w|=k.
Paso inductivo:
Sea w una cadena tal que |w|=k+1, es decir, podemos reescribir w así: w=uak+1 con |u|=k,
u=a1a2…ak. Luego,
Dw(t*)
=Dua(k+1)(t*) pues w=uak+1
=Da(k+1)[Du(t*)] por la regla para cadenas
k
=Da(k+1)[{ Du(t) +
[ D u1 ( t )]... [ D
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
um ( t )]
D a i ...a k ( t)
}t*]
por hipótesis inductiva con u=a1a2…ak
k
= Da(k+1)[ Du(t)t + *
[ D u1 ( t)]... [ D u m ( t)] D a i ...a k ( t) t* ]
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
distribuyendo t*
ahora aplicaremos la regla para + y derivaremos cada miembro respecto de ak+1
para el segundo miembro aplicaremos además I y III
k
=Da(k+1)[Du(t)t*] +
[ D u1 ( t )]... [ D
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
um ( t )]
D
a k1 [ D a i ...a k ( t ) t*]
ahora aplicaremos la regla para la concatenación en ambos casos
102
=Da(k+1)[Du(t)]t*+[Du(t)]Da(k+1)(t*)
k
+
[ D u1 ( t )]... [ D
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
um ( t )]
D D
a k1 a i ...a k ( t ) t* D a i ...a k ( t ) D a k 1 ( t*)
ahora aplicaremos la regla para cadenas y la regla para *
=Dua(k+1)(t) t + [Du(t)]Da(k+1)(t) t*
*
+
k
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
[ D u1 ( t)]... [ D u m ( t)] D a i ...a k a k1 ( t) t* D a i ...a k ( t) D a k1 ( t) t * ]
ahora distribuiremos las sumatorias y haremos uak+1=w
= Dw(t) t* + [Du(t)]Da(k+1)(t) t*
k
+
[ D u1 ( t)]... [ D u m ( t)] D a i ...a k a k1 ( t) t* ]
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
k
+
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
[ D u1 ( t)]... [ D u m ( t)] D a i ...a k ( t) D a k1 ( t) t* ]
ahora aplicaremos la regla de distribución ‘factorizando’ t*
y colocaremos el segundo término al final haciendo u=a1a2…ak
={ Dw(t)
k
+
[ D u1 ( t)]... [ D u m ( t)] D a i ...a k a k1 ( t) ]
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
k
+
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
[ D u1 ( t)]... [ D u m ( t)] D a i ...a k ( t) D a k1 ( t) ]
+ [Da1...ak(t)]Da(k+1)(t) } t*
(la sumatoria interna del segundo término sólo llega hasta a1…ai-1,
y como i puede ser a lo más k se tiene a1a2…ak-1, fíjese como la función
más interna del tercer término junto al último término cubren el
caso a1…ak)
nótese que con las dos sumatorias junto a [Da1...ak(t)]Da(k+1)(t)
se obtiene la siguiente igualdad:
k 1
={ Dw(t) +
[
D u1 ( t )]... [ D
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
um ( t )]
D a i ...a k1 ( t) } t*
103
Un importante resultado es que el número de derivadas distintas que se pueden obtener a
partir de una e.r. es finito, es decir, sea el alfabeto sobre el que se forman las e.r. y sea r una
e.r.:
{Dw(r) / w*} es finito.
Demostración:
Por inducción sobre la longitud de la e.r. r
Caso base:
Sea r una e.r. de longitud |r|=1, es decir r= o r= o r=a (a )
i. Cuando r= es fácil ver de nuestras reglas que Dw()= para todo w, es decir hay una
derivada, no infinitas derivadas distintas.
ii. Cuando r= las reglas permiten evidenciar que Dw()= para w=, Dw()= para w, es
decir hay dos derivadas diferentes, no infinitas derivadas distintas.
ii. Cuando r=a es fácil ver que según nuestras reglas Dw(a)=a para w=, Dw(a)= para w=a y
Dw(a)= para (w y wa), es decir hay tres derivadas diferentes, no infinitas derivadas
distintas.
Hipótesis inductiva:
Una e.r. r de longitud |r|<k tiene un número finito de derivadas distintas que se pueden
obtener a partir de ella.
Paso inductivo:
Sea r una e.r. de longitud |r|=k
Entonces, de acuerdo a la estructura de las e.r., r=s+t o r=st o r=t*
i.Cuando r=s+t, Dw(s+t)=Dw(s) + Dw(t), y de ahí por hipótesis inductiva cada miembro de esta
e.r. tiene un número finito de derivadas distintas, luego r tiene un número finito de derivadas
distintas.
n
ii.Cuando r=st, Dw(st)=Dw(s)t +
i 2
[Da1...ai-1(s)) Dai...an(t)] + (s)Dw(t), y de ahí por
hipótesis inductiva cada miembro de esta e.r. tiene un número finito de derivadas distintas,
luego r tiene un número finito de derivadas distintas.
iii.Cuando r= t*,
n
Dw(t*)={ Dw(t) +
[ D u1 ( t )]... [ D
i 2 1 m i 1 u1 ,..., u mu j & a1 ...a i1 u1 ...u m
um ( t )]
D a i ...a n ( t)
}t*,
y de ahí por hipótesis inductiva esta larga e.r. tiene un número finito de derivadas distintas,
luego r tiene un número finito de derivadas distintas.
104
Un resultado más ambicioso es el siguiente –que busca un número límite superior de
derivadas distintas-:
D
n
Dw(t*)={ a i ...a n ( t) }t*
i 1
={Da1...an(t)+Da2...an(t)...+Da(n-1)an(t)+Dan(t)}t*
Luego
{Dz(t*) / z *} = {[Da1...a|z|(t)+Da2...a|z|(t)+...+Da|z|(t)] t* / z *}
¿ cuántas e.r. distintas [Da1...a|z|(t)+Da2...a|z|(t)...+Da|z|(t)] para z * pueden haber sabiendo
que dt = | {Dz(t) / z *} | ?
Es posible, para cadenas z dadas, que alguna de estas e.r. distintas sea un elemento
de {Dz(t) / z *}, o la suma –en términos de e.r.- de dos elementos cualesquiera
de dicho conjunto, o de todos sus elementos (siempre tomando en cuenta que r+s=s+r y
que r+r=r) eso no es otra cosa que el conjunto de partes de {Dz(t) / z *} excepto el
conjunto vacío, es decir, si hacemos dr=| {Dz(t*) / z *} | entonces dr 2dt - 1
105
n
Dw(st)=Dw(s)t +
i 1
Dai...an(t)
Esta idea de una ecuación puede extenderse a varias ecuaciones, es decir, un sistema de
ecuaciones. Por ejemplo:
1) x1(a+b)x2
2) x2a*+x3
3) x3b+c*
Asimismo la idea de sustitución se aplica naturalmente, por ejemplo sustituyendo 3) en 2):
x2a* + b+c*
Si L(r) entonces la ecuación tiene infinitas soluciones xr*(s+t), donde t representa
cualquier e.r.
Si L(r) entonces la ecuación tiene una única solución xr*s.
Demostración:
i) Si L(r) entonces la ecuación tiene una única solución xr*s
Que r*s sea solución se comprueba sustituyendo este valor en la ecuación. En efecto,
x r*s (r*)s (rr*+)s (rr*s+s) rr*s+s r(r*s)+s r(x)+s rx+s
Probaremos ahora, por reducción al absurdo, que esta solución es única.
Supongamos pues que hay otra solución con cadenas diferentes adicionales a las que denota
r*s, es decir supongamos que xr*s+p, donde p es una e.r., es solución también y que
L(p) L(r*s)=, para que esta sea una otra solución es claro que L(p).
Si r*s+p es solución –como estamos suponiendo- satisface la ecuación, es decir,
r*s+pr(r*s+p)+s
pero r(r*s+p)+srr*s+rp+srr*s+s+rp(rr*s+s)+rp(rr*+)s+rpr*s+rp
106
Luego,
r*s+pr*s+rp
Es decir, L(r*s+p)=L(r*s+rp), o lo que es lo mismo L(r*s) L(p)=L(r*s) L(rp)
Como esta igualdad se cumple podemos intersectar ambos miembros de ella con otro conjunto
y la igualdad debiera persitir, haremos la intersección con L(p):
Lado izquierdo: [L(r*s) L(p)]L(p)=[L(r*s) L(p)] [L(p)L(p)]= L(p)=L(p)
Derecho: [L(r*s) L(rp)] L(p)=[ L(r*s) L(p)] [L(rp)L(p)]=L(rp)L(p)
Como la igualdad se cumple resulta
L(p)=L(rp)L(p)
Sea w la cadena más pequeña de L(p) –existe pues el supuesto es que L(p)-; a partir de la
última igualdad es claro que también w L(rp)L(p), es decir, también w L(rp), es
decir, también w L(r).L(p), por lo tanto w=uv con u L(r), v L(p), sabemos que u
pues L(r), y por lo tanto que |u|>0, lo que quiere decir que |v|<|w| con v L(p), pero esto
es absurdo pues w es la cadena más pequeña de L(p).
Este absurdo muestra que nuestro supuesto está equivocado y que no hay otra solución
además de xr*s.
ii) Si L(r) entonces la ecuación tiene infinitas soluciones xr*(s+t), donde t representa
cualquier e.r.
Que r*(s+t) sea solución, para cualquier e.r. t, se comprueba sustituyendo este valor en la
ecuación como lo haremos enseguida.
Conviene establecer un hecho previo, si L(r) entonces de acuerdo a la definición de e.r. y
el lenguaje que denota: r* rr*
En efecto, sea L=L(r), como L, podemos reescribir L así L=({} L’). Luego,
L(rr*)=L(r).L(r*)=L(r).[ L(r)]*=L.[L]*=L.L*
=L.[{} L L.L L.L.L ...]
=L.{} L.L L.L.L L.L.L.L ...
= L L.L L.L.L L.L.L.L ...
=({} L’) L.L L.L.L L.L.L.L ...
=({} {} L’) L.L L.L.L L.L.L.L ...
={} ({} L’) L.L L.L.L L.L.L.L ...
={} L L.L L.L.L L.L.L.L ...
=L*
=L(r*)
Hagamos la sustitución ahora, todo es evidente a partir de las equivalencias conocidas y del
anterior resultado cuyo uso hemos subrayado:
x r*(s+t) r*s+r*t r*s+rr*t (r*)s+rr*t (rr*+)s+rr*t (rr*s+s)+rr*t
(rr*s+s)+rr*t rr*s+s+rr*t rr*s+rr*t+s r[r*s+r*t]+s r[r*(s+t)]+s r[x]+s rx+s
107
Ejemplos adicionales de autómatas
Note que los estados tienen subíndices que reflejan el número de a’s (mod 3) y el número de
b’s (mod 3); por ejemplo q01 indica que el número de a’s (mod 3) es 0 y que el número de b’s
(mod 3) es 1.
L={ u / Na(u) mod 3 > Nb(u) mod 3 }
Sea A=(K, , , q0, {qf}) un -AFN con T(A)=L y tal que no existen transiciones a q0 ni
tampoco transiciones que salgan de qf .
Si a partir de a construimos el -AFN A’ añadiendo una -transición de q0 a todos los estados
alcanzables desde q0 ((a lo largo de un camino cuyas etiquetas puedan incluir símbolos de Σ,
así como ), entonces T(A’)=Suffix(L), el lenguaje de los sufijos de L.
108
Sea A=(K, , , q0, {qf}) un -AFN con T(A)=L y tal que no existen transiciones a q0 ni
tampoco transiciones que salgan de qf .
Si a partir de a construimos el -AFN A’ añadiendo una -transición a qf desde todos los
estados que puedan alcanzar qf (a lo largo de un camino cuyas etiquetas puedan incluir
símbolos de Σ, así como ), entonces T(A’)=Prefix(L), el lenguaje de los prefijos de L.
Sea A=(K, , , q0, {qf}) un -AFN con T(A)=L y tal que no existen transiciones a q0 ni
tampoco transiciones que salgan de qf .
Si a partir de a construimos el -AFN A’ añadiendo una -transición de q0 a todos los estados
alcanzables desde q0 ((a lo largo de un camino cuyas etiquetas puedan incluir símbolos de Σ,
así como ) y añadiendo una -transición a qf desde todos los estados que puedan alcanzar qf
(a lo largo de un camino cuyas etiquetas puedan incluir símbolos de Σ, así como ), entonces
T(A’)=Infix(L), el lenguaje de las subcadenas de L.
109
CAPÍTULO 9. CONVERSIONES GENÉRICAS: El caso regular
Construcción de una GRLD cuyo símbolo raíz no aparezca en ninguna parte derecha de
las producciones
Por ejemplo G=({S},{a},{S-->aS,S-->a},S) incluye a su símbolo raíz S en la parte derecha de
la primera de sus producciones, G’=({S’,A},{a},{S’-->aA,A-->aA,S’-->a,A-->a},S’) en
cambio no incluye a su símbolo raíz S’ en la parte derecha de ninguna de sus producciones, y
ambas gramáticas generan el mismo lenguaje.
Sea G=(N, T, P, S) tal que L(G)=L y G incluye a su símbolo raíz S en la parte derecha de
alguna(s) de sus producciones, entonces podemos construir una GRLD G’ tal que G’ no
incluya a su símbolo raíz en la parte derecha de ninguna de sus producciones y L(G’)=L(G).
Demostración:
Construimos G’ así: G’=(N { S’ }, T, P’, S’) S’ es un nuevo No Terminal, S’ N
P’ = P { S’ --> / S --> P }
Es obvio que S’ no aparecerá en ninguna parte derecha porque S’ no es un símbolo de G (es
nuevo), es decir, no está en ningún .
i) Sea u L, entonces u L(G) pues L=L(G), es decir, S=>* u con las producciones de P.
Podemos desglosar esta derivación en su primer paso y el resto de los pasos:
S=>=>* u donde los pasos de derivación se dan utilizando producciones de P
denota la cadena que se deriva de S en el primer paso de derivación
que ha debido utilizar la producción S--> P
Por la forma de nuestra construcción, entonces S’--> P’, por lo tanto
S’=> donde en este primer paso se utiliza una producción de P’
=>*u con producciones de P’, en realidad las mismas producciones de P que en la
derivación S=>=>* u, es claro que estas producciones también están en P’.
Es decir, S’=>* u, es decir, u L(G’). Lo que prueba que L(G) L(G’).
ii) Inversamente sea u L(G’), es decir, S’=>* u con producciones de P’
Podemos desglosar esta derivación en su primer paso y el resto de los pasos:
S’=>=>* u donde los pasos de derivación se dan utilizando producciones de P’
denota la cadena que se deriva de S’ en el primer paso de derivación
que ha debido utilizar la producción S’--> P’
Por la forma de nuestra construcción, el único modo de que exista la producción S’--> en P’
es que provenga de la existencia de la producción S--> P.
Precisamente por ello, ya hicimos notar que es evidente que no incluye a S’, por lo tanto el
resto de los pasos de derivación (=>* u) que se dieron utilizando producciones de P’, han
debido darse con las producciones de P que son parte de P’ y son las únicas que quedan en P’
de acuerdo a nuestra construcción.
110
Es decir, es posible que S=>=>* u con sólo producciones de P, es decir, u L(G), lo que
prueba que L(G’) L.
Es decir, L(G’)=L(G), y G’ no incluye a S’ –su símbolo raíz- en ninguna parte derecha de sus
producciones.
Ejemplo:
Sea la GRLD G=({S,B},{a,b},P,S)
P:
S-->aS
S-->bB
B-->bS
S-->a
Construimos así la GRLD G’=({S,B,S’},{a,b},P’,S’)
P’:
S’-->aS
S’-->bB
S’-->a
S-->aS
S-->bB
B-->bS
S-->a
Que no tiene a S’ en ninguna de sus partes derechas y genera el mismo lenguaje que G.
Sea G=(N, T, P, S) una GRLD tal que L(G)=L, entonces podemos construir una GRLI G’ tal
que L(G’)=L(G)
111
Demostración:
Sin pérdida de generalidad -por la anterior conversión- podemos suponer que G es tal que sus
producciones no incluyen a su símbolo raíz en la parte derecha de ninguna de sus
producciones. Entonces construimos así G’=(N, T, P’, S)
P’:
Y --> Xa si ( X --> aY P ) y X S
S --> Xa si ( X --> a P ) y X S
S --> a si ( S --> a P )
Y --> a si ( S --> aY P )
Es claro que las producciones de P’ respetan el formato de las GRLI’s.
i) Sea uL(G) , es decir, S=>* u con las producciones de P.
Si dicha derivación se hace en un paso S=>u, entonces S-->u P, y por lo tanto –tercera línea
de la construcción de P’- S-->u P’, así S=>*u con una producción de P’, es decir, uL(G’).
Si la derivación S=>* u con producciones de P se hace en más de un paso, podemos desglosar
esta derivación, suponiendo lícitamente que u=bi1bi2...bikbik+1 con bij T, así:
S=>bi1Vj1 donde se ha utilizado la producción S-->bi1Vj1 P
=>bi1bi2Vj2 donde se ha utilizado la producción Vj1-->bi2Vj2 P
...
=>bi1bi2... bikVjk donde se ha utilizado la producción Vjk-1-->bikVjk P
=>bi1bi2... bikbk+1 donde se ha utilizado la producción Vjk-->bik+1 P
Ningún Vjh es S, pues G no incluye al símbolo raíz en la parte derecha de sus producciones.
Luego, por la forma de nuestra construcción, las siguientes producciones deben estar en P’:
Vj1-->bi1
Vj2-->Vj1bi2
...
Vjk-->Vjk-1bik
S-->Vjkbik+1
Luego, la siguiente derivación es posible en G’:
S=>Vjkbik+1=>Vjk-1bikbik+1=>...=>Vj2bi3...bikbik+1=>Vj1bi2bi3...bikbik+1=>bi1bi2bi3...bikbik+1
Es decir, S=>*u en G’, es decir u L(G’). Lo que prueba que L(G) L(G’).
ii) Inversamente, sea u L(G’):
Si S=>u en un paso, ello sucede utilizando la producción S-->u P’, pero –por construcción,
tercera línea- esta producción está en P’ sólo cuando S-->u P, así S=>u también en G.
Si S=>*u en G’ dando más de un paso, podemos desglosar esta derivación, suponiendo
lícitamente que u=bi1bi2...bikbik+1 con bij T, así:
S=>Vjkbik+1 donde se ha debido utilizar la producción S-->Vjkbik+1 P’
=>Vjk-1bikbik+1 donde se ha debido utilizar la producción Vjk-->Vjk-1bik P’
...
=>Vj2bi3...bikbik+1 donde se ha debido utilizar la producción Vj3-->Vj2bi3 P’
=>Vj1bi2bi3...bikbik+1 donde se ha debido utilizar la producción Vj2-->Vj1bi2 P’
=>bi1bi2... bikbk+1 donde se ha debido utilizar la producción Vj1-->bi1 P’
112
Estas producciones están en P’ fruto de nuestra construcción y les haremos un análisis tanto
para mostrar que ningún Vjh es S como para indicar qué producciones están en P.
La inclusión de S-->Vjkbik+1 a P’ ha utilizado necesariamente la segunda línea de nuestra
construcción a partir de Vjk-->bik+1 en P, con VjkS.
La inclusión de Vjk-->Vjk-1bik a P’ ha utilizado la primera línea de nuestra construcción a partir
de Vjk-1-->bikVjk en P, con Vjk-1S. No ha podido usarse la segunda línea pues en ese caso
Vjk=S lo que ya está descartado.
Podemos seguir desarrollando un razonamiento análogo recurrente para indicar que:
La inclusión de Vj3-->Vj2bi3 a P’ ha utilizado la primera línea de nuestra construcción a partir
de Vj2-->bi3Vj3 en P, con Vj2S. No ha podido usarse la segunda línea pues en ese caso Vj3=S
lo que ya está descartado.
La inclusión de Vj2-->Vj1bi2 a P’ ha utilizado la primera línea de nuestra construcción a partir
de Vj1-->bi2Vj2 en P, con Vj1S. No ha podido usarse la segunda línea pues en ese caso Vj2=S
lo que ya está descartado.
La inclusión de Vj1-->bi1 a P’ ha utilizado la cuarta línea de nuestra construcción a partir de
S-->bi1Vj1 en P. No ha podido usarse la tercera línea pues en ese caso Vj1=S lo que ya está
descartado.
Así pues, tenemos en P las producciones:
Vjk-->bik+1
Vjk-1-->bikVjk
...
Vj2-->bi3Vj3
Vj1-->bi2Vj2
S-->bi1Vj1
Donde ningún Vjh es S.
Luego, la siguiente derivación es posible en G:
S=>bi1Vj1=>bi1bi2Vj2=>bi1bi2bi3Vj3=>...=>bi1bi2bi3...bikVjk=>bi1bi2bi3...bikbik+1
Es decir, u L(G). Lo que prueba que L(G’) L(G).
Ambas inclusiones demuestran que L(G’)=L(G), y es claro que G’ es una GRLI.
Ejemplo:
A partir de la GRLD G (sólo mostramos P):
P:
S --> aX
X --> aX nótese que G no incluye a su símbolo raíz en
X --> bX la parte derecha de ninguna de sus producciones
X --> b
113
P’:
X --> a
X --> Xa
X --> Xb
S --> Xb
114
Y por lo tanto la siguiente derivación es posible en G:
q1=>bi1qj1=>bi1bi2qj2 =>...=>bi1bi2...bik-2q jk-2=>bi1bi2...bik-2bik-1qjk-1
=>bi1bi2...bik-2bik-1bikqjk=>bi1bi2...bik-2bik-1bikbik+1
Es decir, q1=>*bi1bi2...bik-2bik-1bikbik+1, es decir, u L(G).
Lo que prueba que T(A)-{} L(G).
ii) Inversamente, sea u L(G):
Si q1=>u en un paso de derivación, ello sucede utilizando la producción q1-->u P, pero por
construcción esta producción está en P sólo cuando en A tenemos la regla (q1,u)=qj (qj F),
así *(q1,u) F, es decir, u T(A).
Si q1=>*u en G dando más de un paso, podemos desglosar esta derivación, suponiendo
lícitamente que u=bi1bi2...bikbik+1 con bij T, así:
q1=>bi1qj1 donde se ha debido utilizar la producción q1-->bi1qj1 P
=>bi1bi2qj2 donde se ha debido utilizar la producción qj1-->bi2qj2 P
...
=>bi1bi2...bik-2q jk-2 donde se ha debido utilizar la producción qjk-3-->bik-2qjk-2 P
=>bi1bi2...bik-2bik-1qjk-1 donde se ha debido utilizar la producción qjk-2-->bik-1qjk-1 P
=>bi1bi2...bik-2bik-1bikqjk donde se ha debido utilizar la producción qjk-1-->bikqjk P
=>bi1bi2...bik-2bik-1bikbik+1 donde se ha debido utilizar la producción qjk-->bik+1 P
Estas producciones están en P fruto de nuestra construcción y su presencia se debe solamente
a que en A existen las siguientes reglas de transición:
(q1,bi1)=qj1
(q j1,bi2)=qj2
...
(q jk-3,bik-2)=qjk-2
(q jk-2,bik-1)=qjk-1
(q jk-1,bik)=qjk
(q jk,bik+1)=qj con qj F
A partir de estas reglas es fácil describir una serie de transiciones así:
(q1,bi1bi2...bikbik+1)|--(q j1,bi2bi3...bikbik+1) utilizando la regla (q1,bi1)=qj1
|--(q j2,bi3...bikbik+1) utilizando la regla (q j1,bi2)=qj2
...
|--(q jk-1,bikbik+1) utilizando la regla (q jk-2,bik-1)=qjk-1
|--(q jk,bik+1) utilizando la regla (q jk-1,bik)=qjk
|--(q j,) utilizando la regla (q jk,bik+1)=qj con qj F
Es decir, (q1,bi1bi2...bikbik+1)|-- *(q j,) con qj F, es decir, u T(A).
Lo que prueba que L(G) T(A).
Recuérdese que en la demostración de T(A)-{} L(G) se descarta el caso u=.
Ambas inclusiones junto al último comentario demuestran que L(G)=T(A)-{}, y es claro que
G es una GRLD.
115
Ejemplo:
Sea A=({q1,q2}, {a}, , q1, {q1})
:
(q1,a)=q2
(q2,a)=q1
116
Por nuestra construcción, a partir de dichas reglas de transición, debemos tener las siguientes
producciones en P:
q1-->bi1qj1
q j1-->bi2qj2
...
q jk-2-->bik-1qjk-1
q jk-1-->bikqjk
q jk-->bik+1
Y por lo tanto la siguiente derivación es posible en G:
q1=>bi1qj1=>bi1bi2qj2 =>...=>bi1bi2...bik-2q jk-2=>bi1bi2...bik-2bik-1qjk-1
=>bi1bi2...bik-2bik-1bikqjk=>bi1bi2...bik-2bik-1bikbik+1
Es decir, q1=> bi1bi2...bik-2bik-1bikbik+1, es decir, u L(G).
*
117
Es decir, una de las ramas del árbol de transiciones es tal que podemos escribir
(q1,bi1bi2...bikbik+1)|-- *(q j,) con qj F, es decir, u T(A).
Lo que prueba que L(G) T(A).
Recuérdese que en la demostración de T(A)-{} L(G) se descarta el caso u=.
Ambas inclusiones junto al último comentario demuestran que L(G)=T(A)-{}, y es claro que
G es una GRLD.
Ejemplo:
Sea A=({q1,q2,q3}, {a,b,c}, d, q1, {q1,q2,q3})
d:
d(q1,a)={q2,q3}
d(q2,b)={q2}
d(q3,c)={q3}
118
de A esta regla de transición está en A solamente cuando S-->u P, así S=>*u con una
producción de P, luego u L(G).
Si la transición desde S hacia algún estado final consumiendo la cadena u se hace en más de
un movimiento, podemos desglosar estas transiciones, suponiendo lícitamente que
u=bi1bi2...bikbik+1 con bij T, de la siguiente manera, donde debe tenerse en cuenta que esta es
una de las transiciones posibles –la que nos lleva de S hacia el único estado final qf- pues por
el no determinismo el árbol de transiciones puede tener muchas ramas más:
(S,bi1bi2...bikbik+1)|--(X j1,bi2bi3...bikbik+1) utilizando una regla donde Xj1 d(S,bi1)
|--(X j2,bi3...bikbik+1) utilizando una regla donde Xj2 d(X j1,bi2)
...
|--(X jk-1,bikbik+1) utilizando una regla donde Xjk-1 d(X jk-2,bik-1)
|--(X jk,bik+1) utilizando una regla donde Xjk d(X jk-1,bik)
|--(qf,) utilizando una regla donde qf d(X jk,bik+1) con qf F
Por la construcción de A estas regla de transición están en A solamente cuando las siguientes
producciones están en P:
S-->bi1Xj1
X j1-->bi2Xj2
...
X jk-2-->bik-1Xjk-1
X jk-1-->bikXjk
X jk-->bik+1
Y por lo tanto la siguiente derivación es posible en G:
S=>bi1Xj1=>bi1bi2Xj2 =>...=>bi1bi2...bik-2X jk-2=>bi1bi2...bik-2bik-1Xjk-1
=>bi1bi2...bik-2bik-1bikXjk=>bi1bi2...bik-2bik-1bikbik+1
Es decir, S=> bi1bi2...bik-2bik-1bikbik+1, es decir, u L(G).
*
119
d(S,bi1) con X j1 d(S,bi1)
d(X j1,bi2) con Xj2 d(X j1,bi2)
...
d(X jk-2,bik-1) con Xjk-1 d(X jk-2,bik-1)
d(X jk-1,bik) con Xjk d(X jk-1,bik)
d(X jk,bik+1) con {qf} d(X jk,bik+1)
A partir de estas reglas es fácil describir una serie transiciones así –aunque por el no
determinismo es posible que existan otras ramas en el árbol de transiciones-:
(S,bi1bi2...bikbik+1)|--(X j1,bi2bi3...bikbik+1)
|--(X j2,bi3...bikbik+1)|-- ... |--(X jk-1,bikbik+1)|--(X jk,bik+1)|--(q f,)
Es decir, una de las ramas del árbol de transiciones permite escribir lo siguiente
(S,bi1bi2...bikbik+1)|-- *(q f,) con qf F, es decir, u T(A).
Lo que prueba que L(G) T(A).
Ambas inclusiones demuestran que L(G)=T(A), y es claro que A es un AFN.
Ejemplo:
Sea G=({S,B}, {a,b}, P, S)
P:
S-->aB
B-->bS
B-->b
120
A partir de esta construcción es claro que ’ (la segunda línea de ’ dice prácticamente
que copiemos ), por lo tanto es obvio que si qi K entonces *(qi,w)=’*(qi,w).
También es claro que ninguna regla de transición tiene a q0 como imagen, es decir, ningún
arco llega a q0 que es el estado inicial.
Sea u= T(A), eso ocurre si y sólo si *(q1,)=q1 y q1 F, lo cual ocurre si y sólo si en A’
F’=F {q0}, es decir, si y sólo si *(q0,)=q0 y q0 F’, es decir, si y sólo si u= T(A’).
Sea u T(A) con u=bw, es decir, *(q1,u) F, si y sólo si
(q1,bw)|--(qh,w) utilizando la regla (q1,b)=qh
|--*(q j,) donde *(q h,w)=qj con qj F
Por nuestra construcción eso ocurre si y sólo si en A’ tenemos la regla ’(q0,b)=qh[=(q1,b)],
y si y sólo si *(q h,w)=’*(q h,w)=qj con qj F’ (pues F F’), es decir,
si y sólo si en A’ es posible la siguiente serie de transiciones:
(q0,bw)|--(qh,w) utilizando la regla ’(q0,b)=qh
|--*(q j,) pues *(q h,w)=’*(q h,w)=qj con qj F’ (pues F F’)
es decir si y sólo si ’*(q0,u) F’, o lo que es lo mismo, u T(A’).
Ejemplo:
Sea el AFD A=({q1,q2}, {a,b}, , q1, {q1})
:
(q1,a)=q1
(q1,b)=q2
(q2,a)=q1
(q2,b)=q2
Construimos así el AFD A’=({q1,q2,q0}, , ’, q0, {q1,q0})
’:
’(q0,a)=q1
’(q0,b)=q2
’(q1,a)=q1
’(q1,b)=q2
’(q2,a)=q1
’(q2,b)=q2
121
La construcción alternativa obtiene el siguiente AFD A’=({q1,q2,qf}, {a,b}, ’, q1, {q1,qf})
’:
’(q1,a)=qf
’(q1,b)=q2
’(q2,a)=qf
’(q2,b)=q2
’(qf,a)=qf
’(qf,b)=q2
Ejemplo:
Sea el AFD A=({q1,q2}, {a,b}, q1{q2})
:
(q1,a)=q2 (q1,b)=q2
(q2,a)=q2 (q2,b)=q2
122
Construimos así el AFN A’=({q1,q2}, {a,b}, dq1{q2})
d:
d(q1,a)={q2}
d(q1,b)={q2}
d(q2,a)={q2}
d(q2,b)={q2}
Nótese la importantísima diferencia formal de que las reglas tengan como imagen estados en
el caso del AFD y conjuntos de estados en el caso del AFN.
123
Construimos el AFD A’ así:
A’=(K’, {a,b}, , Q1, F’)
K’={ {q1}, {q2}, {q1,q2}, {} } = {Q1, Q2, Q3, Q4}
Para construir F’ debemos averiguar cuáles Qi entran a este conjunto:
así:
Para Q1: Q1 F={q1} {q1,q2}={q1} y por tanto (Q1 F) {}, luego Q1 entra a F’
Para Q2: Q2 F={q2} {q1,q2}={q2} y por tanto (Q2 F) {}, luego Q2 entra a F’
Para Q3: Q3 F={q1,q2} {q1,q2}={q1,q2} y por tanto (Q3 F) {}, luego Q3 entra a F’
Para Q4: Q4 F={} {q1,q2}={} y por tanto (Q4 F) ={}, luego Q4 no entra a F’
Luego, F’={Q1, Q2, Q3}
:
(Q1,a) = d(p,a) = d(p,a) = d(q1,a) = {q1} = Q1
p Q1 p {q1}
(Q4,a) =
p Q4
d(p,a) =
p {}
d(p,a) = {} = Q4
(Q4,b) =
p Q4
d(p, b) =
p {}
d(p, b) = {} = Q4
Resumiendo, el AFD A’=({Q1, Q2, Q3, Q4}, {a,b}, , Q1, {Q1, Q2, Q3})
:
(Q1,a) = Q1
(Q1,b) = Q2
(Q2,a) = Q3
(Q2,b) = Q4
(Q3,a) = Q3
(Q3,b) = Q2
(Q4,a) = Q4
(Q4,b) = Q4
124
Cuya gráfica es:
125
Sorprendentemente los AFN’s –aunque parecen- no son más poderosos que los AFD’s.
Hay ciertos casos en los que la construcción de un AFD a partir de un AFN se simplifica
(puede retomarse la misma idea también con -AFN’s); considere por ejemplo el siguiente
AFN A=({q1,q2}, {a,b}, d, q1, {q2}) d: d(q1,a)=d(q1,b)=d(q2,a)={q2}
No es que haya no determinismo -al contrario, dado un estado y un símbolo el siguiente
estado está bien determinado salvo para el estado q2 y el símbolo b- sino que únicamente hay
ausencia de algunas reglas de transición, falta(n) algún(os) par(es) estado/símbolo que
llegue(n) a -o cuya imagen sea- un único estado; cierta literatura denomina a este tipo de
autómatas ‘AFD’s incompletos’ (siguiendo esta línea se define el determinismo cuando
|d(qi,cj)|1); nosotros los seguiremos llamando AFN’s, y su conversión a AFD requiere
simplemente la inclusión de las reglas de transición que faltan, como indicamos ahora.
Dado un AFN A=(K, , d, q1, F) del tipo descrito con |K|=n, se construye así el AFD
A’=(K {qn+1}, , , q1, F) tal que T(A)=T(A’)
:
(qn+1,a) = qn+1 a
(qi,a) = qj si d(qi,a)={qj}
= qn+1 si d(qi,a)={}
qn+1 se denomina estado muerto o estado trampa y también suele denotarse con qm.
Ejemplo:
Sea el AFN A=({q1,q2}, {a,b}, d, q1, {q2}) d: d(q1,a)=d(q1,b)=d(q2,a)={q2}
126
Ejemplo:
Dado el AFD A=({q1,q2}, {a,b}, , q1, {q2})
:
(q1,a)=(q1,b)=(q2,a)=(q2,b)=q2
Construimos así el AFD A’=({q1,q2,qm}, {a,b,c}, ’, q1, {q2}) nótese el alfabeto {a,b,c}
’:
’(q1,a)=’(q1,b)=’(q2,a)=’(q2,b)=q2
’(q1,c)=’(q2,c)=qm
’(qm,a)=’(qm,b)=’(qm,c)=qm
Este resultado se puede utilizar para hacer iguales los alfabetos de entrada de dos AFD’s
distintos A1 y A2, con alfabetos 1 y 2 respectivamente (1 2), podemos construir los
autómatas A’1 y A’2, con el alfabeto extendido ’=(1 2), de manera que A’1 y A’2
trabajan con el mismo alfabeto.
127
Construimos el AFN A’ así:
A’=({q1,q2,q3}, b,c}, d’, q1, F’)
F’={q1,q2,q3} pues el cierre({q1})={q1,q2,q3} y por tanto (cierre({q1}) F)
d’:
d’(q1,b) = -cierre d(p, b) = -cierre
d(p, b)
p cierr e({q1}) p {q1 ,q 2 ,q 3}
= -cierre(d(q1,b) d(q2,b) d(q3,b))
= -cierre( {q2} ) =-cierre({q2}) = {q2}
d’(q1,c) = -cierre d(p,c) = -cierre
d(p,c)
p cierr e({q1}) p {q1 ,q 2 ,q 3}
= -cierre(d(q1,c) d(q2,c) d(q3,c))
= -cierre( {q3}) =-cierre({q3}) = {q3}
d’(q2,b) = -cierre d(p, b) = -cierre
d(p, b)
p cierr e({q 2 }) p {q 2 }
= -cierre(d(q2,b))
= -cierre({q2}) = {q2}
d’(q2,c) = -cierre d(p,c) = -cierre
d(p,c)
p cierr e({q 2 }) p {q 2 }
= -cierre(d(q2,c))
= -cierre() = {}
d’(q3,b) = -cierre d(p, b) = -cierre
d(p, b)
p cierr e({q 3}) p {q 3}
= -cierre(d(q3,b))
= -cierre() = {}
d’(q3,c) = -cierre d(p,c) = -cierre
d(p,c)
p cierr e({q 3}) p {q 3}
= -cierre(d(q3,c))
= -cierre({q3}) = {q3}
Resumiendo –no anotamos las reglas de transición cuya imagen es el conjunto vacío-:
A’=({q1,q2,q3}, b,c}, d’, q1, {q1,q2,q3})
d’:
d’(q1,b)={q2} d’(q1,c)={q3}
d’(q2,b)={q2} d’(q3,c)={q3}
128
Cuya gráfica es:
El caso |u|>0 requiere algunos interesantes y no muy simples resultados previos. Veamos.
Probaremos primero que -cierre(-cierre(C))=-cierre(C).
Para ello debemos recordar la definición recursiva del -cierre(C) y utilizaremos lo que se
denomina una prueba por inducción estructural.
De la definición (inciso i) es claro que -cierre(C)-cierre(-cierre(C)).
Mostraremos ahora que si q-cierre(-cierre(C)) entonces q-cierre(C).
Caso base: Debemos mostrar (trabajando el inciso i) que si q-cierre(C) entonces
q-cierre(C), lo que es obvio.
Hipótesis inductiva: Si q-cierre(-cierre(C)) entonces q-cierre(C)
129
Paso inductivo: (Trabajaremos el inciso ii) Sea p-cierre(-cierre(C)), ello debe suceder
porque pd(q,) con q-cierre(-cierre(C)). Pero entonces, por hipótesis inductiva,
q-cierre(C) y como pd(q,), precisamente por el inciso ii, p-cierre(C).
Esto nos ayuda a utilizar un resultado valioso, en los -AFN’s: -cierre(d(qi,w))= d(qi,w)
Ello es evidente pues si w=, tenemos que
-cierre(d(qi,)) = -cierre(-cierre({qi})) por definición de d
= -cierre({qi}) por el resultado que se acaba de probar
= d (qi,) por definición de d
Si w=ua, tenemos que
-cierre(d(qi,w)) = -cierre(d(qi,ua))
= -cierre(-cierre d(p,a) ) por definición de d
p d*( q i ,u)
= -cierre d(p,a) por el resultado que se acaba de probar
p d*( q i ,u)
= d(qi,ua) = d(qi,w)
Ahora probaremos que si CQ, entonces -cierre(C)-cierre(Q), es decir, dado que CQ
mostraremos que si q-cierre(C) entonces q-cierre(Q).
Caso base: Es claro, de la definición (inciso i), que Q-cierre(Q); como tenemos que CQ,
resulta que C-cierre(Q), es decir, que si qC entonces q-cierre(Q).
Hipótesis inductiva: Si q-cierre(C) entonces q-cierre(Q)
Paso inductivo: (Trabajaremos el inciso ii) Sea p-cierre(C), ello debe suceder porque
pd(q,) con q-cierre(C). Pero entonces, por hipótesis inductiva, q-cierre(Q) y como
pd(q,), precisamente por el inciso ii, p-cierre(Q).
Seguidamente probaremos que -cierre(C Q) = -cierre(C) -cierre(Q).
Es claro que tanto C(CQ) como Q(CQ), por el anterior resultado entonces
-cierre(C)-cierre(CQ) y -cierre(Q)-cierre(CQ), de donde
-cierre(C) -cierre(Q)-cierre(CQ).
Resta probar que-cierre(CQ) -cierre(C) -cierre(Q), es decir, que
si q-cierre(CQ) entonces q[-cierre(C) -cierre(Q)].
Caso base: Si q(CQ), entonces [qC ó qQ], luego (inciso i de la definición de -cierre)
[q-cierre(C) ó q-cierre(Q)], es decir, q[-cierre(C) -cierre(Q)].
Hipótesis inductiva: Si q-cierre(CQ) entonces q[-cierre(C) -cierre(Q)].
Paso inductivo: (Trabajaremos el inciso ii de la definición de -cierre).
Sea p-cierre(CQ), ello debe suceder porque pd(q,) con q-cierre(CQ). Pero
entonces, por hipótesis inductiva, q[-cierre(C) -cierre(Q)] y como pd(q,),
precisamente por el inciso ii, p[-cierre(C) -cierre(Q)].
Estábamos queriendo demostrar que en la construcción del AFN A’ a partir del -AFN A
T(A)=T(A’) y restaba demostrar que esto es así en el caso |u|>0.
130
Ello se simplifica si evidenciamos que d’(q1,u) = d(q1,u), lo que haremos por inducción
sobre |u|.
Caso base.
|u|=1, es decir, u=a
d’(q1,a) = d’(q1,a) por un resultado ya conocido
= d(q1,a) por la forma de construir d’
Hipótesis inductiva.
El resultado se mantiene para |u|=k
Paso inductivo.
Sea |u|=k+1, podemos suponer lícitamente que u=wa con |w|=k, luego
d’(q1,wa) = d'(p,a) por definición de d’
p d '*( q1 , w )
= -cierre
d(p,a) utilizando otra vez (**)
p cierre({q } ... {q })
j1 jn
131
= -cierre d(p,a)
p cierre( d*( q1 ,w ))
= -cierre d(p,a)
pues ya demostramos que -cierre(d(q1,w))=d(q1,w)
p d*( q1 ,w )
= d*(q1,wa) por definición de d*
Los tres casos confirman que d’(q1,u) = d(q1,u) para |u|>0.
Ahora bien, sea u T(A), es decir d(q1,u) F, pero entonces d’(q1,u) F y como
F F’, entonces d’(q1,u) F’, es decir, u T(A’).
Inversamente, sea u T(A’), es decir d’(q1,u) F’, pero entonces d(q1,u) F’ y
como F’=F (trataremos enseguida el caso F’=F {q1}) entonces d(q1,u) F, es decir,
uT(A).
Cuando F’=F {q1} y la intersección d(q1,u) F’ cae sólo en elementos de F el argumento
es el mismo.
En el último caso de análisis supongamos que F’=F {q1} y q1 F (cuando q1 F, F’=F lo
que nos remite a algo ya tratado). q1 se incluye a F’ porque cierre({q1}) F, en este
caso hay un(os) estado(s) en cierre({q1}) y en F diferente(s) de q1, vamos a mostrar que
el(ellos) está(n) en d(q1,u), de este modo d(q1,u) F, y por lo tanto u T(A).
En efecto, sabemos que d’(q1,u) F’, es decir, d(q1,u) F’, supongamos también
que la interseción se da (también) en q1 (en otro caso la intersección se da sólo con elementos
de F lo cual ya fue tratado), es decir q1 d(q1,u), o sea podemos escribir lo siguiente:
d(q1,u)={q1} {elrestoded(q1,u)}. Sabemos que -cierre(d(q1,u))=d(q1,u), de ahí es lícito
escribir d(q1,u)=-cierre(d(q1,u))=-cierre({q1} {elrestoded(q1,u)})
=-cierre({q1}) -cierre({elrestoded(q1,u)})
El último paso se dio por un resultado ya visto. Pero -cierre({q1}) Fy q1 F, es decir
que en d(q1,u) hay elementos de F –que no son q1- que es lo que queríamos probar.
Así T(A)=T(A’).
132
Ejemplo:
Con el mismo AFN A = ({q1,q2,q3}, b,c}, d, q1, {q1,q2,q3})
d:
d(q1,)={q2,q3}
d(q2,b)={q2}
d(q3,c)={q3}
El AFN A’=({q1,q2,q3}, b,c}, d’, q1, F’)
0 1 1
+
Tenemos ya calculado R = 0 0 0 y por tanto
0 0 0
F’={q1,q2,q3}
d’:
d’(q1,b) = d(q1,b) d(q j , b) = d(q1,b) d(q2,b) d(q3,b)
( q1 , q j ) R
133
Podemos construir un AFN A (denominado autómata de posición, autómata Glushkov o
autómata de McNaughton-Yamada debido a sus descubridores) a partir de una e.r. asignando
posiciones a los símbolos de dicha expresión regular. Por ejemplo sea r=a(ba) una e.r.,
designaremos las posiciones con subíndices de izquierda a derecha así: r’=a1(b2a3)
El conjunto de símbolos subindizados –denominado conjunto de posiciones- de una e.r. r,
donde los subíndices indican la posición que ocupa el símbolo en la e.r. leída de izquierda a
derecha, lo denominaremos pos(r), en nuestro ejemplo pos(r)={a1,b2,a3}. Al construir pos(r)
no colocaremos subíndices a ni a , si están presentes en r.
Cuando una e.r. no es elemental (r=ts ó r=t+s) denotaremos con
posr(t) al subconjunto de posiciones de t que son posiciones de r; y con
posr(s) al subconjunto de posiciones de s que son posiciones de r.
Por supuesto esta idea es recurrente si a su vez t o s son e.r. no elementales, en nuestro
ejemplo r=ts con t=a1 y s=(b2a3), de este modo posr(s)={b2,a3}; a su vez s=(b2a3) es otra vez
de la forma no elemental pues s=t’s’ con s’=a3, cuyo conjunto de posiciones es {a3}, etc.
La idea ahora es asignar a cada símbolo subindizado un estado del autómata y dirigir un arco
de un estado a otro según el símbolo denotado en el estado de llegada siga o no al símbolo
denotado en el estado de partida en las cadenas en L(r). Los índices cuentan y sirven para este
propósito, en el ejemplo que tenemos una a1 nunca seguirá a una b2 pero si una a3, nótese
cómo los índices hacen cambiar el significado de estas frases pues sin índices es claro que una
a sigue a una b en la(s) cadena(s) de L(r).
La construcción del AFN exige construir los siguientes conjuntos para la e.r r –lo cual,
insistimos, requiere de la vital subindización de las posiciones-:
primer(r)={todos los primeros símbolos de cadenas en L(r)}
Para nuestro ejemplo primer(r)={a1}
último(r)={todos los últimos símbolos de cadenas en L(r)}
Para nuestro ejemplo último(r)={a3}
siguiente(r,ci)={todos los símbolos que siguen al símbolo ci en cadenas en L(r)}
Para nuestro ejemplo siguiente(r,a1)={b2}; siguiente(r,b2)={a3}; siguiente(r,a3)={}
Es claro que si la e.r. es más compleja los conjuntos a construirse requieren de más
herramientas que la simple inspección, por ejemplo en r=a*b*a*, es decir, en r’=a1*b2*a3*
no es muy inmediato ver que b2 pertenece a último(r).
Las siguientes definiciones recurrentes –que son bastante intuitivas- permiten hallar estos
conjuntos mecánicamente, en ellas ci es un símbolo subindizado de la e.r.
r=: primer() = {}
r=: primer() = {}
r=a: primer(a) = {a}
r=t+s: primer(t+s) = primer(t) primer(s)
r=t*: primer(t*) = primer(t)
r=ts: primer(ts) = primer(t) primer(s) si L(t)
= primer(t) si L(t)
134
r=: último() = {}
r=: último () = {}
r=a: último(a) = {a}
r=t+s: último(t+s) = último(t) último(s)
r=t*: último(t*) = último(t)
r=ts: último(ts) = último(t) último(s) si L(s)
= último(s) si L(s)
r=: siguiente(,ci) = {}
r=: siguiente(,ci) = {}
r=a: siguiente(a,ci) = {}
r=t+s: siguiente(t+s,ci) = siguiente(t,ci) si ci posr(t)
= siguiente(s,ci) si ci posr(s)
r=t*: siguiente(t*,ci) = siguiente(t,ci) si ci posr(t)-último(t)
= siguiente(t,ci) primer(t) si ci último(t)
r=ts: siguiente(ts,ci) = siguiente(t,ci) si ci posr(t)-último(t)
= siguiente(t,ci) primer(s) si ci último(t)
= siguiente(s,ci) si ci posr(s)
Una vez que para la e.r. r se tienen los conjuntos pos(r), primer(r), último(r) y siguiente(r,ci)
para cada ci que aparece en r se construye el AFN A así:
A=( pos(r) {q0}, , d, q0, F)
={ a / ci pos(r) y [ci]=a } o bien es el alfabeto sobre el cual se construyó r
F = último(r) {q0} si L(r)
último(r) si L(r)
135
d:
d(q0,a)={ cj / cj primer(r) y [cj]=a }
d(ci,a)={ cj / cj siguiente(r,ci) y [cj]=a }
Ejemplo:
Sea r=(ab+ac)d*
Construimos así el AFN A tal que T(A)=L(r)
r’=(a1b2+a3c4)d5*
pos(r)={a1,b2,a3,c4,d5}
Ahora construimos los tres conjuntos detallando sólo algunas de las partes de la construcción,
en todo caso simplemente aplicaremos lo descrito antes.
136
siguiente(r,a1)=siguiente(t,a1)=siguiente(a1b2+a3c4,a1)
=siguiente(a1b2,a1) pues a1 pos(a1b2)
=siguiente(a1,a1) primer(b2) pues a1 último(a1)={a1}
={} {b2}={b2}
Otra idea muy popular debida a Thompson construye -AFN’s con la propiedad de tener un
único estado final del que no salen arcos y un estado inicial al que no llegan arcos.
137
A la e.r. a le corresponde el siguiente -AFN:
Toda e.r. es una combinación de estas e.r. básicas, utilizando los operadores ‘+’, ‘.’ y ‘*’.
En la tabla siguiente At denota el -AFN para la e.r. t, As denota el -AFN para la e.r. s, se
supone que ya se tienen construidos ambos -AFN’s y por ello se los grafica dentro de un
recuadro, a la e.r. de la izquierda le corresponde el -AFN de la derecha
r=ts:
El estado final de At es solapado por el
estado inicial de As.
r=t+s:
La línea punteada indica un estado que
era final en el autómata original
(At o As) pero que ya no lo es en la
construcción que se plantea.
r=t*:
La línea punteada indica el estado final
del autómata At pero que ya no lo es en
la construcción que se plantea.
138
Ejemplo:
Sea r=(ab+ac)d*
Construimos así el -AFN A tal que T(A)=L(r), es claro que los subíndices de los estados
deben adecuarse a la construcción, así lo haremos renombrando si es necesario.
Para la e.r. a (de manera semejante para b, c y d) el -AFN es:
139
Se construye un gtg con la e.r. r así A=({q1,qf},{r},d,q1,{qf}) donde d: d(q1,r)={qf}, y a partir
de dicho gtg se van construyendo nuevos gtg’s descomponiendo r en sus partes elementales
según se indica a continuación de manera gráfica.
El punteado indica que si qi (ó qj) es un estado final, este preserva dicha cualidad.
Si i=j el reemplazo es equivalente, aunque la gráfica varía obviamente.
qk es un nuevo estado que se añade al gtg
Si una parte del gtg incluye la se la reemplaza por
transición
r=ts:
r=t+s:
r=t*:
Ejemplo:
Sea r=(ab+ac)d*
Construimos así el -AFN A tal que T(A)=L(r)
El gtg inicial es:
140
Las e.r. ab y ac se tratan de manera semejante a lo que hicimos inicialmente, lo interesante es
observar cómo funciona el reemplazo para d*, todo ello resulta en:
Cuando i=j el tratamiento es el mismo como muestra el siguiente ejemplo del cual no
mostramos todos los detalles.
Sea r=(a*+b)*
Luego de trabajar la ‘*’ más externa tenemos:
Otra alternativa debida a Brzozowski es utilizar las derivadas de la e.r. r para construir el
AFD. Esta idea procede de dos maneras, una manera obtiene un AFD con el menor número
posible de estados y la otra un AFD cualquiera posiblemente con muchos estados, explicamos
ambas a continuación.
141
Sea r una e.r. construida sobre , construimos el AFD A con el menor número posible de
estados tal que T(A)=L(r) así:
A=(K, , , r, F)
K={Dw(r) / w*} recuerde que este conjunto es finito, note que los estados son e.r.
F={ Dw(r) / L(Dw(r))}
: ( Dw(r),a) = Dwa(r)
Una forma más gráfica de ver esta construcción es como sigue.
Construimos un árbol de e.r. con r como nodo raíz.
Se deriva el árbol por niveles -desde el nodo raíz- respecto a cada símbolo de , cada una de
estas derivadas es un nuevo nodo y el arco que enlaza una e.r. y su derivada se etiqueta con el
símbolo utilizado para la derivación:
- la derivada se compara con todas las e.r. de los nodos existentes hasta el momento y si es
equivalente a alguna e.r. previa entonces el nombre del nodo resultante –la derivada- se
reemplaza por dicha e.r. previa.
- si es equivalente a el nombre del nodo resultante es precisamente .
Se cierra una rama del árbol si el nombre del nodo es idéntico a algún otro nodo ya existente
en el árbol o si es .
Cuando todas las ramas del árbol estén cerradas (lo que se garantiza por la finitud de las
derivadas de una e.r.), se construye el AFD así:
Los estados son los nombres de los nodos del árbol. De acuerdo a lo descrito puede haber más
de un nodo con el mismo nombre a los que les corresponde un único estado.
Son estados finales los nodos cuyo lenguaje asociado a su e.r. incluya la cadena vacía.
De cada nodo padre a un nodo hijo hay una regla de transición con el símbolo que etiqueta el
arco que los une. Si el árbol incluye un nodo con nombre , este estado es el equivalente al
estado muerto o trampa y de ahí hay reglas a sí mismo con todos los símbolos de .
Ejemplo:
Sea r=(ab+ac)d*
Construimos así el AFD A tal que T(A)=L(r)
Primero construimos el árbol de derivadas a partir de nodo raíz con etiqueta (ab+ac)d*.
Derivamos esta e.r. respecto de a, b, c y d. Cada resultado es un nuevo nodo.
142
Es vital comparar cada nuevo nodo con los existentes previamente para ver si son e.r.
equivalentes y hacer lo que indica el procedimiento.
Note por ejemplo que con la e.r. (b+c)d* la derivada respecto de b -Db[(b+c)d*]- es d* que es
inexistente en el segundo nivel y que obviamente no es equivalente a Da[(b+c)d*]=. En
cambio Dc[(b+c)d*] es también d* y por lo tanto esta rama se cierra pues esta e.r. ya existe.
Hemos representado con una x pequeña el hecho de que una rama se cierre.
A=(K,,,r=q1,F)
K={(ab+ac)d*, (b+c)d*, d*, } que pueden renombrarse como K={q1,q2,q3,qm }
={a,b,c,d}
Es claro que d* pero no a las otras e.r. de K, es decir F={q3}
:
(q1,a)=q2 (q1,b)=qm (q1,c)=qm (q1,d)=qm
(q2,a)=qm (q2,b)=q3 (q2,c)=q3 (q2,d)=qm
(q3,a)=qm (q3,b)=qm (q3,c)=qm (q3,d)=q3
(qm,a)=qm (qm,b)=qm (qm,c)=qm (qm,d)=qm
Uno de los obstáculos de esta alternativa es tener que averiguar la equivalencia entre e.r. que
puede no ser un trabajo elemental ni rápido; por ejemplo si el nodo raíz fuese r=(a*+ba*+b*)*
y derivamos r respecto de a y b se tiene:
Da(a*+ba*+b*)*=a*(a*+ba*+b*)* ¡que es equivalente a r!
Db(a*+ba*+b*)*=(a*+b*)(a*+ba*+b*)* ¡que es equivalente a r!
Por lo tanto los nombres de los nodos de las derivadas se reemplazan por la e.r. previa
existente en el árbol que no es otra que r. Así el árbol para esta e.r. -que no contiene a - es:
143
Brzozowski plantea un procedimiento muy semejante al anterior con la diferencia que ahora
se compara la derivada –el nombre del nodo- no para ver si es equivalente sino simplemente si
es similar a alguno de los nodos existentes hasta el momento en el árbol (el conjunto de
derivadas similares de una e.r. es también finito); el resto del procedimiento es exactamente
igual. El AFD resultante aquí no es necesariamente uno con el menor número posible de
estados.
Ejemplo:
Para el caso r=(a*+ba*+b*)* el árbol de derivadas considerando solamente similaridad es el
que se muestra enseguida; todas las ramas están cerradas –aunque no hemos colocado las x- y
el autómata correspondiente con cuatro estados se construye como indica el procedimiento
descrito.
Hay otras alternativas que simplemente mencionamos como las derivadas parciales de e.r.
propuesta de Antimirov que devuelve un AFN o el llamado Follow Automaton.
Construcción de una e.r. a partir de un autómata A (el Teorema de Kleene parte II)
Sea A un AFD entonces puede denotarse T(A) en términos de e.r.
Demostración:
Sea A=(K, , , q1, F) con K={q1,...,qn}
Definiremos las siguientes expresiones regulares:
ri,jn es una e.r. que denota al siguiente conjunto de cadenas:
L(ri,jn ) = { u / (qi,u)=qj
y
el AFD no pasa por ningún estado qm con m > n al consumir u
excepto posiblemente el primer estado y el último estado }
144
Es decir, ri,jn denota todas las cadenas u que me llevan de qi a qj pero que son tales que al ir de
qi a qj no pisamos, no atravesamos, no pasamos por ningún estado qm cuyo subíndice m sea
mayor que n. Esta restricción de que m no sea mayor que n no incluye al estado de partida ni al
estado de llegada.
Otra forma equivalente de indicar el conjunto de cadenas que denota esta expresión regular es
así:
L(ri,jn ) = { es el conjunto de cadenas u=a1a2...apap+1 tales que
(qi,a1)=qj1
(qj1,a2)=qj2
...
(qjp-1,ap)=qjp
(qjp,ap+1)=qj
donde j1,j2,...,jp n }
Fíjese que la restricción j1,j2,...,jp n no afecta al estado de partida qi ni al de llegada qj
Cada L(ri,jn) puede obtenerse de lenguajes -conjuntos de cadenas- finitos a través de un número
finito de aplicaciones de las operaciones , * y . (unión, estrella de Kleene y concatenación
) permitidas sobre lenguajes.
La prueba del enunciado se hace por inducción sobre n:
Caso base:
Para n=0 el resultado es evidente puesto que L(ri,j0) es un conjunto finito de cadenas.
L(ri,j0) = { a / (qi,a)=qj } si i j.
L(ri,i0) = { a / (qi,a)=qi } {} si i = j
Puesto que cualquier cadena de longitud mayor a 1 atravesará por algún estado cuyo subíndice
es mayor que 0 (recuerde que nuestros subíndices empiezan en 1).
Es claro que estos son conjuntos finitos de cadenas.
Hipótesis inductiva:
Asumimos que el enunciado es cierto para n=k
Paso inductivo:
Para n=k+1 tenemos esta ingeniosa relación que prueba lo deseado y que se autoexplica:
L(ri,jk+1) = L(ri,jk ) { L(ri,k+1k) . (L(rk+1,k+1k))*. L(rk+1,jk) }
Finalmente el broche de oro está cuando notamos que
T(A) = L(r1,jn)
q j F
Sólo nos resta probar que para cada L(ri,jn) existe una e.r.
Para n=0
ri,j0 = aj1 + ... + ajm si i j y (qi,ajh)=qj
ri,i = aj1 + ... + ajm +
0
si i = j y (qi,ajh)=qi
Y asumiendo que para n=k el enunciado es cierto se tiene
para n=k+1
ri,jk+1 = { ri,jk } + { [ri,k+1k] . (rk+1,k+1k)*. [rk+1,jk] }
donde hemos usado llaves, paréntesis y corchetes sólo con fines de claridad.
145
La e.r s para T(A)=L(s) sería así: s = r1,j1n + ... + r1,jhn para todo qji F
La anterior prueba no es otra cosa que un instrumento para hallar T(A) de manera mecánica,
en términos de expresiones regulares, sin embargo se advierte que la e.r. resultante puede ser
muy larga y se recomienda su simplificación haciendo uso de las equivalencias ya conocidas.
Ejemplo:
Sea el AFD A=({q1,q2}, {a,b}, , q1, {q1})
:
(q1,a)=q1
(q1,b)=q2
(q2,a)=q1
(q2,b)=q2
T(A)=L(s) donde la e.r. s = r1,12
Cuando se pueda es mejor simplificar las e.r. resultantes a través de las equivalencias
conocidas.
r1,10 = a+
r1,11 = r1,10 + [r1,10].(r1,10)*.[r1,10]
= a+ + [a+](a+)*[a+] = a+{(a+)*[ a+]} = (a+)(a+)* = (a+)* = a*
0
r1,2 = b
r1,21 = r1,20 + [r1,10].(r1,10)*.[r1,20]
= b + [a+](a+)*[b] = {[a+](a+)*}b = {(a+)*}b = a*b
0
r2,1 = a
r2,11 = r2,10 + [r2,10].(r1,10)*.[r1,10]
= a + [a](a+)*[a+] = a{(a+)*[ a+]} = a(a+)* = aa*
0
r2,2 = b+
r2,21 = r2,20 + [r2,10].(r1,10)*.[r1,20]
= b+ + [a](a+)*[b] = +b + a(a+)*b = + [ + a(a+)*]b = + [+aa*]b = +a*b
r1,1 = r1,11 + [r1,21].(r2,21)*.[r2,11]
2
= a* + [a*b](+a*b)*[aa*] = a* + [a*b](a*b)*[aa*]
= a* + [a*b](a*b)*[ a*a] = a* + a*b (a*b)*a* a = a* + a*b (a+b)* a = a*[+ b(a+b)*a]
146
A cada estado qi en el -AFN se asocia una incógnita xi cuya ecuación xi ... se escribe así:
xi cxj +
qj d ( qi ,c)
si qi F
cx
qj d ( qi ,c)
j en otro caso
Es decir, en la parte derecha se añade -suma en términos de e.r.- cxj si qj d(qi,c) con
c({}), si qi F entonces también se añade .
Una vez que tenemos para cada uno de los n estados una incógnita y su ecuación asociada
estamos en la presencia de un sistema de n ecuaciones con n incógnitas, donde es claro que
podemos utilizar las equivalencias r+rr, r+ss+r, (r+s)+tr+(s+t), rrr, rr y
r++rr.
Ahora aplicamos recurrentemente el Lema de Arden a través del siguiente procedimiento que
elimina una incógnita y una ecuación a la vez y que lo aplicaremos sistemáticamente desde xn
hasta x1 (es claro que este orden puede cambiarse).
Podemos considerar cada ecuación de la forma genérica
xi ci1x1+ ... +cinxn+t (t= o t= dependiendo si qi es final o no)
Y reordenarla de manera que la incógnita esté también al principio en la parte derecha así:
xi ciixi+ci2x2+ ... +cinxn+t
Es interesante notar que esta ecuación puede lícitamente verse también así:
xi ciixi+r donde r=ci2x2+ ... +cinx+t, r no incluye a xi
Ya vimos la demostración de Arden que xi=cii*r es solución de esta ecuación.
Así pues podemos aplicar dicha reordenación para cada ecuación y donde sea posible
reemplazar las soluciones que vayamos encontrando para las incógnitas. Al final tendremos
una ecuación con una incógnita que también se soluciona con el Lema de Arden obteniendo la
e.r. requerida en la solución para x1 que representa al estado inicial q1.
Ejemplo:
Sea el AFD A=({q1,q2}, {a,b}, , q1, {q1})
:
(q1,a)=q1
(q1,b)=q2
(q2,a)=q1
(q2,b)=q2
Construimos la e.r. s tal que T(A)=L(s) así:
x1 ax1+bx2+
x2 bx2+ax1
Para x2: x2bx2+[ax1] con r=ax1, luego x2=b*ax1
Para x1: x1ax1+bx2+ haciendo el reemplazo para x2 tenemos:
x1ax1+bb*ax1+ que reordenando resulta en:
x1(a+bb*a)x1+con r=, luego x1=(a+bb*a)*
147
Una otra alternativa elimina estados del gtg correspondiente al -AFN haciendo que en los
arcos queden e.r. cada vez más cercanas a T(A).
Sin pérdida de generalidad exigiremos que al estado inicial no lleguen arcos y que haya un
único estado final del que no salen arcos. Es decir, dado el -AFN A’=(K’, , d’, q1, F’)
construimos así el -AFN A=(K, , d, q0, F)
Con K = K’ {q0,qf}
F = {qf}
d:
d(q0,) = {q1}
d(qi,cj) = d’(qi,cj) si qi K’-F’, cj {} ó si qi F’, cj
d’(qi,cj) {qf } si qi F’, cj =
Lo que se hace luego es transformar el gtg correspondiente al -AFN en otro gtg que no tenga
varios arcos y etiquetas que vayan de un mismo estado de partida a un mismo estado de
llegada, por ejemplo d(qi,)={qj}, d(qi,a)={qj}, d(qi,b)={qj},..., d(qi,z)={qj}, que se ve así:
Sustituyendo esas etiquetas y/o arcos con una única e.r. así:
Se hace una sustitución similar cuando el arco de partida y el de llegada son el mismo.
Este nuevo gtg tiene una sola etiqueta por arco y un sólo arco entre un estado de partida y un
estado de llegada.
A continuación, básicamente se trata de eliminar los estados uno a uno hasta que queden sólo
los dos nuevos estados añadidos q0 y qf. Al eliminar estados, las etiquetas de los arcos que
queden deben simular a través de e.r. los caminos que pasaban por el estado eliminado, ello se
hace a través del siguiente procedimiento:
Mientras el número de estado del gtg resultante sea > 2:
Elegir un estado qi K-{q0,qf}
Eliminar el estado qi
Es obvio que en algún momento tendremos un gtg con dos estados (q0 y qf), la e.r. que une
ambos estados que denominaremos s es tal que L(s)=T(A).
Aquí supondremos que siempre que se pueda acudiremos a estas equivalencias conocidas:
r+rr, r+ss+r, (r+s)+tr+(s+t), rrr, rr y r++rr, es claro que pueden
utilizarse las otras equivalencias también.
148
La eliminación del estado qi se hace así:
Construir el conjunto de estados desde los cuales se llega a qi (excepto el propio qi), es decir,
los estados predecesores de qi: pre(qi)={ qh / qh K-{qi } y qi d(qh,r), r es una e.r.}.
Construir el conjunto de estados hasta los cuales se llega desde qi (excepto el propio qi), es
decir, los estados sucesores de qi: suc(qi)={ qj / qj K-{qi } y qj d(qi, r), r es una e.r.}.
Eliminar qi y todos sus arcos de salida o llegada.
Para todo par (qh,qj) pre(qi) X suc(qi)], incluidos los pares tales que qh=qj, incluir la
siguiente transición:
qj d(qh,pt*s)
donde
qi d(qh,p) p es la etiqueta del arco que va de qh a qi
qj d(qi,s) s es la etiqueta del arco que va de qi a qj
qi d(qi,t) t es la etiqueta del arco que va de qi a qi si existe, en otro caso t=
Si es necesario se transforman los gtg’s resultantes en otros gtg’s que no tenga varios arcos o
varias etiquetas que vayan de un mismo estado de partida a un mismo estado de llegada como
se indicó atrás.
Ejemplo:
Sea el siguiente -AFN A’=({q1,q2}, {a,b}, d’, q1, {q1})
d’:
d’(q1,a)={q1}
d’(q1,b)={q2}
d’(q2,a)={q1}
d’(q2,b)={q2}
El nuevo -AFN es A=({q0,q1,q2,qf}, {a,b}, d, q0, {qf}):
d:
d(q0,)={q1}
d(q1,a)={q1}
d(q1,b)={q2}
d(q2,a)={q1}
d(q2,b)={q2}
d(q1,)={qf}
El gtg es básicamente el mismo salvo que las etiquetas de los arcos serán consideradas e.r.
Eliminamos el estado q1:
pre(q1)={q0,q2}
suc(q1)={q2,qf}
pre(q1) X suc(q1)={(q0,q2),(q0,qf),(q2,q2),(q2,qf)}
Para el par (q0,q2): q2 d(q0,a*b)
Para el par (q0,qf): qf d(q0,a*)
Para el par (q2,q2): q2 d(q2,aa*b)
Para el par (q2,qf): qf d(q2,aa*)
149
Luego de la integración de varias etiquetas el resultante gtg tiene los estados {q0,q2,qf} con
d:
d(q0,a*b)={q2}
d(q0,a*)={qf}
d(q2,aa*b+b)={q2}
d(q2,aa*)={qf}
Eliminamos el estado q2:
pre(q2)={q0}
suc(q2)={qf}
pre(q2) X suc(q2)={(q0,qf)}
Para el par (q0,qf): qf d(q0,a*b[aa*b+b]*aa*)
Luego de la integración de varias etiquetas el resultante gtg tiene los estados {q0,qf} con
d:
d(q0,a*b[aa*b+b]*aa*+a*)={qf}
Que tiene sólo los dos estados añadidos, de donde la e.r. buscada es s=a*b[aa*b+b]*aa*+a*
Ejemplo:
Sea A’=({q1,q2,q3,q4},{a},’,q1,{q2,q3})
’: ’(q1,a)=q2 ’(q2,a)=’(q3,a)=’(q4,a)=q1
Construimos así el AFD accesible A=(K,{a},,q1,F):
B0={q1}
B1={q1} {q2} pues q1B0 y (q1,a)=q2
B2={q1,q2}
Como B1=B2, entonces K=alcanzablesdesdeq1=B1={q1,q2}
F={q2,q3} {q1,q2}={q2}
: (q1,a)=q2 (q2,a)=q1
150
Construcción de un AFD con el menor número posible de estados a partir de un AFD
cualquiera (minimización de AFD’s)
Lo primero que debemos hacer es i) mostrar que para cualquier lenguaje regular existe un
AFD mínimo, es decir, un AFD con el menor número posible de estados; ii) averiguar si este
es único; y iii) indicar una manera algorítmica de obtenerlo.
Para ello debemos recordar el teorema de Myhill-Nerode puesto que se utiliza.
i) Sea L un lenguaje regular, entonces existe un AFD A tal que L=T(A) y A tiene el menor
número de estados posible (A es mínimo).
Demostración:
Es claro que si L es regular debe haber un AFD A’ cualquiera que lo acepte.
Sin embargo recuérdese que el teorema de Myhill-Nerode dice que, si L es regular entonces la
relación RL es de índice finito, y si ello es así entonces la tercera parte del teorema muestra
cómo construir una AFD A tal que T(A)=L a partir de RL.
El AFD A=(K,,,q1,F), construido como se indica en dicho teorema con |K|=n –el índice de
RL es n-, tiene el menor número de estados posible.
En efecto, sea A’=(K’,,’,p1,F’) cualquier otro AFD tal que T(A’)=L con |K’|=m,
mostraremos que mn.
Recordemos que en K cada estado es una clase de equivalencia de RL y que hay un número
finito n de clases de equivalencia.
También sabemos que dentro de cada clase los elementos están relacionados entre si, es decir,
si las cadenas x,y pertenecen a una clase es porque xRy, es decir, wxwLywL,
otra manera de decir ello es que w ambas cadenas xw,yw están en L o ambas no lo
están, en este caso se dice que las cadenas x,y son indistinguibles.
Por el contrario si la cadena u está en una clase, y la cadena v está en otra clase entonces las
cadenas u,v se dice que son distinguibles, es decir, w tal que de las dos cadenas uw,vw
sólo una de ellas está en L, es decir, w [(uwL vwL) (uwL vwL)], ello es
obvio puesto que si w uwLvwL las dos cadena u,v estarían relacionadas y en la
misma clase.
A partir de K podemos formar el siguiente conjunto:
S = {x1,...,xn} donde cada xi es un representante de la clase [xi]RL, es decir, tomamos un
elemento cualquiera de cada una de las n clases de K para formar S.
Es evidente que los n elementos de S son distinguibles entre sí.
Mostraremos que cualquier AFD que acepte L –en particular A’- debe tener por lo menos n
estados, es decir, mn:
Sean xi,xj (ij) dos elementos cualesquiera de S, mismos que son –como dijimos- distinguibles
entre sí, es decir w tal que sólo una de las cadenas xiw,xjw está en L, como T(A’)=L se
tiene que la cadena w es tal que sólo una de las cadenas xiw,xjw llega a un estado final de A’
[(’(p1,xiw)F’ ’(p1,xjw)F’) (’(p1,xiw)F’ ’(p1,xjw)F’)], es decir,
’(p1,xiw)’(p1,xjw), una de las cadenas xiw,xjw llega –partiendo de p1- a un estado que es
final y la otra cadena llega a un estado que no es final y por lo tanto diferente.
Sabemos también que ’(p1,xiw)=’(’(p1,xi),w) y que ’(p1,xjw)=’(’(p1,xj),w)
151
De donde tenemos que ’(’(p1,xi),w)’(’(p1,xj),w).
Permítasenos hacer ’(p1,xi)=ph y ’(p1,xj)=pg, luego, ’(ph,w)’(pg,w).
Es evidente que si ph=pg entonces ’(ph,w)=’(pg,w), la contrarrecíproca nos dice que
Si ’(ph,w)’(pg,w) entonces phpg.
Es decir, que para cualesquier par de cadenas xi,xj (ij) de S se tiene que ’(p1,xi)’(p1,xj),
es decir, el AFD A’ llega a estados diferentes con dos cualesquier elementos de S; como S
tiene n elementos entonces el AFD A’ llegará a n estados diferentes, ello sólo puede suceder si
el AFD A’ tiene por lo menos n estados, es decir, mn.
ii) ¿Existirá otro AFD con n estados que acepte L pero que sea diferente de A? La respuesta es
negativa: el AFD mínimo A es único salvo isomorfismos, es decir, salvo que los estados se
renombren.
Demostración:
Sea A=(K,,,[]RL,F) el AFD mínimo que se construye en la tercera parte del teorema de
Nerode, y sea A’=(K’,,’,p1,F’) otro AFD, tales que T(A)=T(A’)=L y |K|=|K’|=n.
Para mostrar que A’ es isomorfo a A, es decir, que los estados de A’ son simplemente un
renombramiento de los de A, identificaremos cada estado de K’ con algún estado de K, tal
identificación supone que el estado de A’ y el correspondiente estado identificado de A se
comportan igual:
Recordemos que el estado inicial de A es []RL y que K={[x]RL / x}
Sea piK’, es obvio que A’ es accesible, luego u ’(p1,u)=pi.
Con la misma cadena u en el AFD A llegamos a ([]RL,u)=[u]RL.
Identificaremos a pi con [u]RL.
Supongamos que hay otra cadena v tal que ’(p1,v)=pi, es claro que en la relación RA’
definida en la primera parte del teorema de Myhill-Nerode uRA’v pues ’(p1,u)=’(p1,v), de
acuerdo a la segunda parte del mencionado teorema también uRLv, es decir, las cadenas u,v
están en la misma clase de equivalencia en RL; de este hecho y dado que ([]RL,u)=[u]RL y
([]RL,v)=[v]RL, se deduce que la clase de equivalencia de u es la misma que la clase de
equivalencia de v, es decir, ([]RL,u)=([]RL,v).
Así pues, con cualquier cadena que llegue a pi en el AFD A’–partiendo de su estado inicial-,
también el AFD A llegará –partiendo de su estado inicial- a [u]RL, es decir, la identificación de
pi con [u]RL es buena pues ambos estados son básicamente el mismo estado sólo que con
diferente nombre en uno y otro autómata pues su comportamiento es idéntico: en efecto,
supongamos que los estados pi y pj de A’ se identifican con los estados [u]RL y [w]RL de A,
ya vimos que cualquier cadena que partiendo del estado inicial de A’ llegue a pi, llegará
también sistemáticamente –partiendo del estado inicial de A- a [u]RL; en A’ cualquier cadena z
que pase por pi y de ahí llegue a pj, se puede subdividir en dos subcadenas z=xy, con la
subcadena x se llega a pi y con la subcadena y se llega de pi a pj –nótese como pi interviene en
esta transición-, análogamente ocurrirá en A, con la cadena z llegaremos a [w]RL,
primeramente con x llegaremos a [u]RL y, de ahí, llegaremos a [w]RL –nótese cómo la
intervención de [u]RL es la misma que de pi-.
152
Finalmente resta argumentar que la identificación de los estados de A’ se hace con estados
diferentes, uno a uno, de A; si no fuera así A’ tendría estados demás y, por lo tanto, no sería
mínimo lo cual era un supuesto de partida.
iii) Se sabe que dado un lenguaje regular tenemos un AFD A’ tal que T(A’)=L. El problema es
ahora, dado L y/o dado A’, cómo construir el AFD mínimo.
Es obvio que dado el AFD A’ podemos hallar primero L(=T(A’)) -o bien tenemos L
directamente-, a partir de éste podemos hallar la relación RL y apelar a la tercera parte del
teorema de Myhill-Nerode para construir el AFD mínimo A.
Ejemplo:
Sea el lenguaje regular L={ u{a,b} / Na(u)=2i Nb(u)=2j; i,j0 }
Las cadenas de L son aquellas que tienen un número par tanto de a’s como de b’s.
Construyamos la partición de inducida por la relación RL, recordando que dos cadenas x,y
están en una misma clase si y sólo sí w{a,b} xw,yw están ambas en L o no lo están.
Cadenas que tienen un número impar de a’s y par de b´s:
[a]RL={ u{a,b} / Na(u)=2i+1 Nb(u)=2j; i,j0 }
Cadenas que tienen un número par de a’s e impar de b´s:
[b]RL={ u{a,b} / Na(u)=2i Nb(u)=2j+1; i,j0 }
Cadenas que tienen un número impar de a’s e impar de b´s:
[ab]RL={ u{a,b} / Na(u)=2i+1 Nb(u)=2j+1; i,j0 }
Cadenas que tienen un número par de a’s y b´s:
[]RL={ u{a,b} / Na(u)=2i Nb(u)=2j; i,j0 }
La tercera parte del teorema de Myhil-Nerode nos dice que:
A=(K,{a,b},,q1,F)
K={[]RL, [a]RL , [b]RL, [ab]RL}={q1,q2,q3,q4}
F={[]RL}={q1}
:
([]RL,a)=[a]RL, es decir,(q1,a)=q2
([]RL,b)=[b]RL, es decir,(q1,b)=q3
([a]RL,a)=[aa]RL, es decir,(q2,a)=q1 nótese que [aa]RL=[]RL
([a]RL,b)=[ab]RL, es decir,(q2,b)=q4
([b]RL,a)=[ba]RL, es decir,(q3,a)=q4 nótese que [ba]RL=[ab]RL
([b]RL,b)=[bb]RL, es decir,(q3,b)=q1 nótese que [bb]RL=[]RL
([ab]RL,a)=[aba]RL, es decir,(q4,a)=q3 nótese que [aba]RL=[b]RL
([ab]RL,b)=[abb]RL, es decir,(q4,b)=q2 nótese que [abb]RL =[a]RL
Sin embargo, en esta construcción la identificación de las clases puede ser árida y nos interesa
particularmente otra idea, la de construir al AFD A a partir del AFD A’ -L=T(A’)- sin hallar
RL.
Sea el AFD accesible A’=(K’,,’,p1,F’) tal que T(A’)=L, ya dijimos cómo construir un AFD
accesible a partir de uno que no lo es.
153
Sobre K’ definiremos la relación E así:
piEpj si y sólo si w ’(pi,w)F’’(pj,w)F’
Que evidentemente es de equivalencia y se denominada relación de equivalencia entre
estados.
Construiremos así el AFD A=(K, , , [p1]E, F) a partir de A’:
K={[pi]E / piK’}, la partición en clases de equivalencia de K’ inducida por la relación E
[p1]E el estado inicial de A es la clase de equivalencia que contiene al estado inicial p1 de A’
F={[pi]E / piF’}
: ([pi]E,a)=[’(pi,a)]E
Luego mostraremos que T(A)=L y que es el AFD mínimo.
Lo que debemos mostrar ahora es cómo construir K:
Para ello definiremos la relación de m-equivalencia Em así:
piEmpj si y sólo si w |w|m ’(pi,w)F’’(pj,w)F’
Mostraremos ahora resultados que nos permitirán construir fácilmente la partición de K’.
1) piEm+1pj => piEmpj
Demostración:
Que piEm+1pj significa que w |w|m+1 ’(pi,w)F’’(pj,w)F’, si esto es cierto
para |w|m+1, obviamente también es cierto para |w|m, es decir,
w |w|m ’(pi,w)F’’(pj,w)F’, es decir, piEmpj
2) piEm+1pj piEmpj a ’(pi,a)Em’(pj,a)
Demostración:
=>) Es claro –por 1- que piEm+1pj => piEmpj
Si mostramos que piEm+1pj => a ’(pi,a)Em’(pj,a), de ambas implicaciones sigue
que piEm+1pj => piEmpj a ’(pi,a)Em’(pj,a).
Si piEm+1pj, entonces w |w|m+1 ’(pi,w)F’’(pj,w)F’, si ello es cierto para
|w|m+1, en particular es cierto para 0<|w|m+1, es decir,
w 0<|w|m+1 ’(pi,w)F’’(pj,w)F’, aprovechando las propiedades de la
concatenación ello puede reescribirse así, con w=au:
a u |u|m ’(pi,au)F’’(pj,au)F’, que por propiedades de ’puede
reescribirse así: a u |u|m ’(’(pi,a),u)F’’(’(pj,a),u)F’, que es lo
mismo que a u |u|m ’(’(pi,a),u)F’’(’(pj,a),u)F’, es decir,
a’(pi,a)Em’(pj,a); así pues piEm+1pj => a ’(pi,a)Em’(pj,a)
<=) Si piEmpj a ’(pi,a)Em’(pj,a), ello significa que
w |w|m ’(pi,w)F’’(pj,w)F’, y que
a w |w|m ’(’(pi,a),w)F’’(’(pj,a),w)F’, esto último es lo mismo que
a w |w|m ’(’(pi,a),w)F’’(’(pj,a),w)F’, que es lo mismo que
a w |w|m ’(pi,aw)F’’(pj,aw)F’, que por concatenación de cadenas
con u=aw, es lo mismo que u 0<|u|m+1 ’(pi,u)F’’(pj,u)F’, como el caso de
la cadena vacia está cubierto por el hecho de que piEmpj, resulta que piEm+1pj.
154
3) Denominaremos Pm a la partición en clases de equivalencia de K’ inducida por Em.
Si Pm=Pm+1 entonces i0 Pm=Pm+i
Demostración:
Por inducción sobre i. Es obvio que el enunciado es cierto para i=0 (y para i=1); supongamos
que es cierto para i=k, mostraremos que es cierto para i=k+1, es decir, mostraremos que
Pm=Pm+k+1. En efecto, sean dos estados tales que piEm+k+1pj, por 1 sabemos que piEm+kpj y por
hipótesis inductiva se tiene que piEmpj; inversamente sean dos estados tales que piEmpj, por el
supuesto de partida (Pm=Pm+1) tenemos que piEm+1pj, por 2 se deduce que
piEmpj a ’(pi,a)Em’(pj,a), por hipótesis inductiva resulta que
piEm+kpj a ’(pi,a)Em+k’(pj,a), y otra vez por 2 finalmente tenemos que piEm+k+1pj.
4) Si Pm=Pm+1 entonces Pm=K
Si piEpj, entonces w ’(pi,w)F’’(pj,w)F’, como es cierto w en particular
es cierto w |w|m, luego w |w|m’(pi,w)F’’(pj,w)F’, es decir, piEmpj.
Inversamente, si piEmpj entonces w |w|m’(pi,w)F’’(pj,w)F’, además como
Pm=Pm+1 por 3 tenemos que k0 piEm+kpj, es decir,
k0 w |w|m+k ’(pi,w)F’’(pj,w)F’, que se puede expresar también así
w’(pi,w)F’’(pj,w)F’, es decir, piEpj.
Estos resultados permiten diseñar el siguiente procedimiento para calcular K:
P0 = { [pj / pjF’], [pj / pj(K’-F’)] }, es decir finales por un lado y no finales por otro
Pi+1 se construye así: dos estados ph,pj están en la misma clase en Pi+1 si están en una misma
clase en Pi y a los estados ’(ph,a),’(pj,a) también están en una misma clase.
Si Pi=Pi+1 entonces Pi=K.
Sólo resta argumentar que algún momento la condición Pi=Pi+1 se cumple, ello es así puesto
que cada refinamiento, es decir cada partición, dividirá las primeras clases a lo más hasta tener
por cada estado una clase, luego no es posible hacer más divisiones o refinamientos.
El caso extremo en el que P0 tiene una sola clase (cuando F=K o cuando F={}), se maneja
igual aunque es inmediato que en este caso P0 será igual a P1 y las reglas de transición van del
único estado a sí mismo con todos los símbolos del alfabeto .
Para construir Pi+1 a partir de Pi lo que hay que ver es si las clases se subdividen, ello puede
hacerse en un cierto modo sistemático así:
Tomando un estado ph de alguna clase en Pi como una especie de pivote y ver si los demás
estados que lo acompañan (en Pi) –por ejemplo pj- siguen acompañándolo en Pi+1 (verificando
si a los estados ’(ph,a),’(pj,a) están en una misma clase en Pi aunque no es necesario
que sea la misma clase en la que están ph y pj).
Los estados que están junto a ph en una misma clase en Pi y que, fruto de la verificación, lo
acompañen en Pi+1, se ponen todos en una misma clase precisamente en Pi+1 y se los
considerará como marcados en Pi; los estados que están junto a ph en una misma clase en Pi y
que, fruto de la verificación, no lo acompañen ya en Pi+1, se los considera como no marcados y
de entre ellos se toma un nuevo pivote (en la clase en Pi) y se procede nuevamente a ver
cuáles de los no marcados lo acompañan del modo sistemático que indicamos.
155
Se hace lo mismo para cada clase en Pi.
Es obvio que si una clase de Pi tiene un solo estado, esta clase ya no se refinará y se repetirá
tal cual en Pi+1.
Ejemplo:
Sea el siguiente AFD accesible A’=({p1,p2,p3,p4,p5},{a,b},’,p1,{p1,p4,p5})
’:
’(p1,a)=p2
’(p1,b)=p3
’(p2,b)=p4
’(p2,a)=’(p3,a)=’(p4,a)=’(p5,a)=p1
’(p3,b)=’(p4,b)=’(p5,b)=p5
156
K={ [p1]E, [p4]E, [p2]E }={ [p1]E, [p5]E, [p3]E }
La clase que contiene al estado inicial de A’ es q1=[p1]E que es el estado inicial de A.
F={ [p1]E, [p4]E }={q1,q2}
Sólo resta construir , por ejemplo ([p4]E,b)=[’(p4,b)]E=[p5]E, es decir,(q2,b)=q2
El resto está aquí
:
(q1,a)=(q1,b)=q3
(q2,a)=(q3,a)=q1
(q2,b)=(q3,b)=q2
157
El AFD A El AFD A
construido según el teorema de Construido según se indica arriba
Myhill-Nerode tiene n estados Tiene –por nuestro supuesto- más de n
los cuales podrían llamarse: estados, digamos n+1 estados, los cuales
representaremos así:
q1 correspondiente a la clase []RL [pi1]E xi1
... ... cada pij es un estado de K’ ...
qj correspondiente a otra clase de RL [pij]E y para cada uno de ellos xij
... ... xij ’(p1,xij)=pij ...
qn correspondiente a la última clase de RL [pin]E pues A’ es accesible, xin
[pin+1]E anotemos estas cadenas xin+1
aquí la derecha
Además estas cadenas son tales que ’(p1,xij)=pij y ’(p1,xih)=pih, con [pij]E y [pih]E dos clases
de equivalencia en la partición de K’ que induce E, es decir, [pij]E y [pih]E son dos estados de
K y [pij]E [pih]E, que es lo mismo que decir que pij y pih no están relacionados (bajo E).
Pero entonces –de acuerdo a la definición de E-:
no es cierto que w ’(pij,w)F’’(pih,w)F’,
en esta expresión podemos reemplazar pij con ’(p1,xij) y pih con ’(p1,xih), luego,
no es cierto que w ’(’(p1,xij),w)F’’(’(p1,xih),w)F’, por propiedades de ’
resulta lo siguiente: no es cierto que w ’(p1,xijw)F’’(p1,xihw)F’,
como A’ acepta L, deducimos esto: no es cierto que w xijwLxihwL,
-nótese la definición de RL-, así pues tenemos que xij no está relacionada con xih (bajo RL).
Líneas arriba concluimos que xijRLxih y ahora concluimos que ello no es cierto, esta
contradicción prueba el enunciado de que A no tiene más estados que A, es decir, es el AFD
mínimo.
Hay una alternativa muy popular aunque exigente en tiempo computacional para calcular las
clases de equivalencia de la partición de K’ inducida por E, en vez de refinar las clases a partir
de P0, lo que hace es averiguar poco a poco cuáles pares de estados son distinguibles, es decir
no equivalentes, para finalmente agruparlos en clases. Se basa en los siguientes resultados:
i) Es obvio que si sólo uno de los dos estados pi,pj está en F’, con w=:
w [{’(pi,w)F’ ’(pj,w)F’} {’(pi,w)F’ ’(pj,w)F’}], es decir,
pi,pj no son equivalentes (bajo E). Esto nos permite identificar los primeros pares de estados
distinguibles, son aquellos en los que uno es final y el otro no.
ii) Si ’(pi,a)=ph y ’(pj,a)=pg y ph,pg son distinguibles entonces pi,pj son distinguibles.
Ello es inmediato puesto que ph,pg sean distinguibles no es otra cosa que
w [{’(ph,w)F’ ’(pg,w)F’} {’(ph,w)F’ ’(pg,w)F’}]; sea la cadena
u=aw, dado que ’(pi,aw)=’(’(pi,a),w)=’(ph,w) y ’(pj,aw)=’(’(pj,a),w)=’(pg,w),
resulta que u [{’(pi,u)F’ ’(pj,u)F’} {’(pi,u)F’ ’(pj,u)F’}] es decir,
pi,pj no son equivalentes (bajo E) o lo que es lo mismo son distinguibles. Esto nos permite
identificar pares de estados distinguibles a partir de otros que ya son distinguibles.
158
La idea se integra en el siguiente procedimiento que construye una matriz de pares de estados
distinguibles, las filas corresponden a estados y las columnas también –la matriz triangular
superior se omite por simetría y porque la diagonal compararía un estado consigo mismo lo
que no tiene sentido pues siempre un estado es indistinguible de sí mismo-:
. Construimos la matriz B marcando toda celda B(i,j) correspondiente al par de estados pi,pj
en el que sólo uno de ellos está en F’.
. Se hace lo siguiente
Se revisan una a una las celdas B(i,j) no marcadas,
a se obtiene ph=’(pi,a) y pg= ’(pj,a)
si la celda B(h,g) está marcada, entonces se marca B(i,j)
hasta que no se añadan marcas en B.
Una vez que se tiene el B final, las celdas marcadas corresponden a los pares de estados
distinguibles; y las celdas no marcadas corresponden a los pares de estados indistinguibles, es
decir, equivalentes, basta reunir estos estados en clases de equivalencia para obtener K.
Si algún estado es tal que toda su fila y toda su columna está marcada –o se omite- este estado
constituye una clase por sí mismo.
Ejemplo:
Sea el siguiente AFD accesible A’=({p1,p2,p3,p4,p5},{a,b},’,p1,{p1,p4,p5})
’:
’(p1,a)=p2
’(p1,b)=p3
’(p2,b)=p4
’(p2,a)=’(p3,a)=’(p4,a)=’(p5,a)=p1
’(p3,b)=’(p4,b)=’(p5,b)=p5
En el primer paso se obtiene la siguiente matriz donde hemos rayado la parte omitida y la
marca utilizada es una x, cada fila corresponde a un estado y cada columna también, así la
primera fila corresponde a p1, etc.:
x
B= x
x x
x x
Como siguiente paso se observa cada celda no marcada -por ejemplo B(4,1) correspondiente
al par p4,p1- y obtenemos ’(p4,a)=p1 y ’(p1,a)=p2, B(1,2)=B(2,1) si está marcado y por tanto
procedemos a marcar también B(4,1); sólo por diferenciar haremos las marcas en este paso
con una X mayúscula. Es claro que si B(2,1) no estuviera marcado debemos seguir probando
con todos los símbolos de .
El resultado es:
159
x
B= x
X x x
X x x
Otra vez observamos cada celda no marcada, y ahora ya no se añaden marcas.
Las celdas no marcadas corresponden a pares de estados indistinguibles o equivalentes
mismos que pasamos a agrupar, así [p3,p2] están en una clase y [p5,p4] están en otra clase.
Es claro también que p1 constituye una clase por sí misma: [p1].
160
CAPÍTULO 10. CERRADURA: El caso regular
La propia definición de e.r. muestra que los lenguajes regulares son cerrados respecto de la
unión, concatenación y estrella de Kleene; además, a partir de las conversiones genéricas, para
e.r. dadas podemos construir autómatas y a partir de ellos gramáticas correspondientes.
Junto a la verificación de la cerradura respecto de otras operaciones, sin embargo, es usual
considerar estos problemas también de manera directa –por ejemplo trabajar exclusivamente
con GRLI’s- sin apelar a las conversiones en uno u otro sentido. Intentaremos mostrar ello
aunque no seremos exhaustivos.
Unión
Los lenguajes regulares son cerrados respecto de la operación unión.
Sean G1=(N1,T1,P1,S1) tal que L(G1)=L1 y G2=(N2,T2,P2,S2) tal que L(G2)=L2 dos GRLD’s con
(N1 2 S N1 y S N2, entonces podemos construir una GRLD G tal que
L(G)=L1L2.
Demostración:
Construimos así la GRLD G=(N,T,P,S)
N = N1 N2 { S }
T = T 1 T2
P = { S --> / ( S1 --> P1 ) ó ( S2 --> P2 ) } P1 P2
Los subíndices de esta construcción deben seguirse bien; representa cualquier parte derecha
(de un símbolo o de dos).
161
Además, como contiene solo símbolos de N1 ó N2 y -precisamente por esto- como ningún
símbolo o producción de P1 aparece en P2 (y viceversa), entonces la derivación =>* u se ha
debido realizar sólo con producciones de P1 ó de P2 (que están en P) por lo tanto, la derivación
que estamos desglosando puede descomponerse así:
S1=>=>*u con producciones de P1, utilizando en el primer paso S1--> ó
S2=>=>*u con producciones de P2, utilizando en el primer paso S2-->
es decir, u L(G1) ó u L(G2).
ii) Inversamente sea u L(G1) ó u L(G2), es decir,
S1=>=>*u con producciones de P1 ó
S2=>=>*u con producciones de P2,
Por la forma de nuestra construcción –dado que P1 P y P2 P- la derivación =>*u puede
hacerse con producciones de P.
Además, por la forma de nuestra construcción, S--> está en P. Luego, es posible que
S=>=>* u con sólo producciones de P, es decir, u L(G).
Ejemplo:
Sea el lenguaje regular L1={ak / k > 0} generado por la GRLD G1=(N1,T1,P1,S1)
N1={S1}
T1={a}
P1:
S1-->aS1
S1-->a
Sea el lenguaje regular L2={bi / i > 0} generado por la GRLD G2=(N2,T2,P2,S2)
N2={S2}
T2={b}
P2:
S2-->bS2
S2-->b
Construimos así la GRLD G=(N,T,P,S) tal que L(G)=L1 L2={ak / k > 0} {bi / i > 0}
N={S,S1,S2}
T={a,b}
P:
S --> a
S --> b
S --> aS1
S --> bS2
S1 --> aS1
S1 --> a
S2 --> bS2
S2 --> b
162
Sean A1=(K1,1, 1, q1, F1) tal que T(A1)=L1 y A2=(K2,2, 2, p1, F2) tal que T(A2)=L2 dos
AFD’s con (K1 2 entonces podemos construir un AFD A tal que T(A)= L1 L2 así:
Por un resultado anterior es posible suponer sin pérdida de generalidad que 1=2=.
A=(K1 X K2, , , [q1,p1], F)
F={ qi,pj] / qi F1 ó pj F2}
: qi,pj],a)=[1qi,a),2pj,a)]
Mostraremos por inducción sobre |u| que qi,pj],u)=[1qi,u),2pj,u)]
Caso base:
|u|=0, es decir u=
qi,pj],u)=qi,pj],) pues u=
=qi,pj] por definición de caso
=1qi,),2pj,)] por definición de 1 y 2 caso
=1 qi,u),2 pj,u)]
pues u=
Hipótesis inductiva:El enunciado es cierto para cadenas de longitud k.
Paso inductivo:
Sea w una cadena de longitud k+1, es decir, w=ua con |u|=k.
qi,pj],w)=qi,pj],ua) pues w=ua
=(qi,pj],u),a) por definición de
=([1qi,u),2pj,u)],a) por hipótesis inductiva
=[1(1qi,u),a),2(2pj,u),a)] por construcción de
=[1qi,ua),2pj,ua)] por definición de
=[1 qi,w),2 pj,w)]
pues w=ua
Ahora bien,
u T(A) si y sólo si q1,p1],u) F -y por la reciente inducción-
si y sólo si [1q1,u),2p1,u)] F –y por construcción de F-
si y sólo si 1q1,u) F1 ó 2p1,u) F2
si y sólo si u T(A1) ó u T(A2)
Ejemplo:
Sean los AFD’s
A1=({q1}, {a,b}, 1, q1, {q1})
1:1q1,a)=1q1,b)=q1 y
A2=({p1,p2}, {a,b}, 2, p1, {p2})
2:2p1,a)=2p1,b)=p2
2p2,a)=2p2,b)=p1
Construimos así el AFD A=({[q1,p1],[q1,p2]}, {a,b}, , [q1,p1], {[q1,p1],[q1,p2]})
:
q1,p1],a)=q1,p1],b)=[q1,p2]
q1,p2],a)=q1,p2],b)=[q1,p1]
163
Concatenación
Los lenguajes regulares son cerrados respecto de la operación concatenación.
Sean G1=(N1,T1,P1,S1) tal que L(G1)=L1 y G2=(N2,T2,P2,S2) tal que L(G2)=L2 dos GRLD’s con
(N1 2 entonces podemos construir una GRLD G tal que L(G)=L1.L2.
Demostración:
Construimos así la GRLD G=(N,T,P,S1)
N = N1 N2
T = T 1 T2
P = [ P1 - { X --> a / X --> aP1 } ] { X --> aS2 / ( X --> aP1 ) } P2
Fíjese que a diferencia de lo que hacíamos en la unión el símbolo raíz de G1 es ahora el
símbolo raíz de G y no se aumentan nuevos No Terminales.
Ejemplo:
Sea el lenguaje regular L1={ak / k > 0} generado por G1=({S1},{a},P1,S1)
P1:
S1-->aS1
S1-->a
Sea el lenguaje regular L2={bi / i > 0 } generado por G2=({S2},{b},P2,S2)
164
P2:
S2-->bS2
S2-->b
Construimos así la GRLD G=(N,T,P,S1) tal que L(G)= L1.L2 = {akbi / k > 0 , i > 0}
N={S1,S2}
T={a,b}
P:
S1 --> aS1
S1 --> aS2
S2 --> bS2
S2 --> b
Ejemplo:
Sean G1=({S1},{a},{S1-->S1a,S1-->a},S1) y G2=({S2},{b},{S2-->S2b,S2-->b},S2) dos GRLI’s,
construimos así la GRLI G=({S1,S2},{a,b},P,S2)
P:
S2-->S2b
S2-->S1b
S1-->S1a
S1-->a
Ejemplo:
Sean A1=({q1,q2}, {a}, d1, q1, {q2}) y A2=({p1,p2}, {b}, d2, p1, {p2}) los -AFN’s con
d1: d1(q1,a)={q2} y d2: d2(p1,b)={p2}
165
Construimos así el -AFN A=({q1,q2,p1,p2}}, {a,b}, d, q1, {p2})
d: d(q1,a)={q2} d(q2,)={p1} d(p1,b)={p2}
Ejemplo:
Sean A1=({q1,q2}, {a}, d1, q1, {q2}) y A2=({p1,p2}, {b}, d2, p1, {p1,p2}) los AFN’s con
d1: d1(q1,a)={q2} y d2: d2(p1,b)={p2}
Construimos así el AFN A=({q1,q2,p1,p2}}, {a,b}, d, q1, {q2,p1,p2})
d: d(q1,a)={q2} d(q2,b)={p2} d(p1,b)={p2}
ii) Si de un estado cualquiera en A1 llego a un estado final (en A1) además debe llegarse al
estado inicial de A2, con el mismo símbolo.
A=(K1 K2, 1 2, d, q1, F)
d: d(pi,a) = d1(pi,a) {p1} si pi K1, [d1(pi,a) F1] F = F2 si L2
d1(pi,a) si pi K1, [d1(pi,a) F1]= F2 F1 si L2
d2(pi,a) si pi K2
Si q1 F1, es decir si L1, la construcción debe complementarse en el caso de q1 así:
d(q1,a) = d(q1,a) d2(p1,a) a (1 2)
Ejemplo:
Sean A1=({q1,q2}, {a}, d1, q1, {q1,q2}) y A2=({p1,p2}, {b}, d2, p1, {p1,p2}) los -AFN’s con
d1: d1(q1,a)={q2} y d2: d2(p1,b)={p2}
Construimos así el AFN A=({q1,q2,p1,p2}}, {a,b}, d, q1, {q1,q2,p1,p2})
d: [inicialmente d(q1,b)={ }] d(q1,a)={q2,p1} d(p1,b)={p2} complementando d(q1,b)={p2}
Diferencia
Los lenguajes regulares son cerrados respecto de la operación diferencia de conjuntos.
Sean A1=(K1,1, 1, q1, F1) tal que T(A1)=L1 y A2=(K2,2, 2, p1, F2) tal que T(A2)=L2 dos
AFD’s con (K1 2 entonces podemos construir un AFD A tal que T(A)= L1-L2.
Demostración:
Por un resultado anterior es posible suponer sin pérdida de generalidad que 1=2=.
Se construye así el AFD A=(K1 X K2, , , [q1,p1], F)
F={ qi,pj] / qi F1 y pj F2 }
: qi,pj],a)=[1qi,a),2pj,a)]
166
Ya demostramos que qi,pj],u)=[1qi,u),2pj,u)], luego
u T(A) si y sólo si q1,p1],u) F
si y sólo si [1q1,u),2p1,u)] F
si y sólo si 1q1,u) F1 y 2p1,u) F2 -por construcción de F-
si y sólo si u T(A1) y u T(A2)
si y sólo si u [T(A1)-T(A2)]
Ejemplo:
Con los mismos AFD’s que para la unión lo único que varía es F que es así:
F={[q1,p1]}
Complemento
Los lenguajes regulares son cerrados respecto del complemento (con * como universo).
Sea A=(K,, , q1, F) tal que T(A)=L un AFD entonces podemos construir otro AFD A’ tal
que T(A’)=*-L.
Demostración:
Se construye así el AFD A’=(K, , , q1, K-F)
u T(A’) si y sólo si q1,u) K-F
si y sólo si q1,u) F
si y sólo si u T(A)
Ejemplo:
Sea el AFD A1=({q1}, {a,b}, 1, q1, {q1})
1:1q1,a)=1q1,b)=q1
Construimos así el AFD A’=({q1}, {a,b}, 1, q1, )
Intersección
Los lenguajes regulares son cerrados respecto de la operación intersección.
Sean A1=(K1,1, 1, q1, F1) tal que T(A1)=L1 y A2=(K2,2, 2, p1, F2) tal que T(A2)=L2 dos
AFD’s con (K1 2 entonces podemos construir un AFD A tal que T(A)= L1 L2.
Demostración:
Por un resultado anterior es posible suponer sin pérdida de generalidad que 1=2=.
Construimos así el AFD A=(K1 X K2, , , [q1,p1], F)
F= F1 X F2
: qi,pj],a)=[1qi,a),2pj,a)]
167
Ya demostramos que qi,pj],u)=[1qi,u),2pj,u)], luego
u T(A) si y sólo si q1,p1],u) F
si y sólo si [1q1,u),2p1,u)] F
si y sólo si 1q1,u) F1 y 2p1,u) F2 -por construcción de F-
si y sólo si u T(A1) y u T(A2)
si y sólo si u [T(A1) T(A2)]
Ejemplo:
Con los mismos AFD’s que para la unión lo único que varía es F que es así:
F={[q1,p2]}
Ejemplo:
Sean las GRLD’s G1=({S1,Y},{a,b},{S1-->aS1,S1-->aY,Y-->b},S1) y
G2=({S2,Z},{a,b},{S2-->aZ, Z-->bZ,Z-->b },S2), construimos así la GRLD G=(N,T,P,[S1,S2])
N={[S1,S2],[S1,Z],[Y,S2],[Y,Z]}
T={a,b}
P:
[S1,S2]-->a[S1,Z]
[S1,S2]-->a[Y,Z]
[Y,Z]-->b
Estrella de Kleene
Los lenguajes regulares son cerrados respecto de la operación estrella de Kleene.
168
Mostraremos la construcción con GRLD’s, en cuyo caso por la excepción de la cadena vacía
hablamos de la operación cruz de Kleene pues la GRLD’s no manejan .
Sea la GRLD G=(N,T,P,S) L(G)=L entonces podemos construir otra GRLD G’ tal que
L(G’)=L*.
Demostración:
Se construye así la GRLD G’=( N,T,P’,S)
P’= P {X-->aS / X-->a P }
i) Sea u L+, es decir, existe un i tal que u Li , es decir, u=u1...ui con uj L=L(G), es
decir, para cada uj S=>*uj, es posible desglosar cada una de estas derivaciones así:
S=>*jXj=>jaj
Donde se ha evidenciado el último paso de derivación de uj=jaj que ha debido utilizar la
producción Xj-->aj P.
Por la forma de nuestra construcción Xj-->ajS P’, luego se deduce que la siguiente
derivación es posible:
S=>*1X1=>1a1S=>...=>*1a1...iXi=>1a1...iai
Es decir, u L(G’).
ii) Inversamente sea u L(G’), es decir, S=>*u.
P’ tiene las mismas producciones de P junto al conjunto {X-->aS / X-->a P }, de ahí que
Esta derivación puede desglosarse así, utilizando las producciones de P y en vez de utilizar
una producción que finalice la derivación de terminales reiniciar el trabajo de las
producciones de P utilizando una del tipo X-->aS que si está en P’ tantas i veces como se
quiera así:
S=>*1X1=>1a1S=>...=>*1a1...iXi=>1a1...iai
Pero entonces u es una cadena con la siguiente forma u=u1...ui con uj L(G)=L, es decir,
u L+.
Ejemplo:
Sea la GRLD G=({S,Y},{a,b},{S-->aS,S-->aY,Y-->b},S), construimos así la GRLD
G’=({S,Y},{a,b},{S-->aS,S-->aY,Y-->b,Y-->bS},S)
Ejemplo:
Sea el AFN A=({q1,q2}, {a}, d1, q1, {q2}) con
d1: d1(q1,a)={q2}
169
Construimos así el AFN A’=({q1,q2}, {a}, d, q1, {q1})
d: d(q1,a)={q2,q1}
170
Si S’=>u en un paso, ello sucede utilizando la producción S’-->u P’, también es claro que
uR=u, pero –por construcción, tercera línea- esta producción está en P’ sólo si S-->u P, así
S=>u también en G.
Si S=>*u en G’ dando más de un paso, podemos desglosar esta derivación, suponiendo
lícitamente que u=bik+1bik...bi1bi2 con bij T, así:
S’=>bik+1Vjk donde se ha debido utilizar la producción S’-->bik+1Vjk P’
=>bik+1bikVjk-1 donde se ha debido utilizar la producción Vjk-->bikVjk-1 P’
...
=>bik+1bik...bi3Vj2 donde se ha debido utilizar la producción Vj3-->bi3Vj2 P’
=>bik+1bik...bi3bi2Vj1 donde se ha debido utilizar la producción Vj2-->bi2Vj1 P’
=>bik+1bik...bi3bi2bi1 donde se ha debido utilizar la producción Vj1-->bi1 P’
Estas producciones están en P’ fruto de nuestra construcción y les haremos un análisis tanto
para mostrar que ningún Vjh es S como para indicar qué producciones están en P.
La inclusión de S’-->bik+1Vjk a P’ ha utilizado necesariamente la segunda línea de nuestra
construcción a partir de Vjk-->bik+1 en P, con VjkS.
La inclusión de Vjk-->bikVjk-1 a P’ ha utilizado la primera línea de nuestra construcción a partir
de Vjk-1-->bikVjk en P, con Vjk-1S. No ha podido usarse la segunda línea pues en ese caso
Vjk=S lo que ya está descartado.
Podemos seguir desarrollando un razonamiento análogo recurrente para indicar que:
La inclusión de Vj3-->bi3Vj2 a P’ ha utilizado la primera línea de nuestra construcción a partir
de Vj2-->bi3Vj3 en P, con Vj2S. No ha podido usarse la segunda línea pues en ese caso Vj3=S
lo que ya está descartado.
La inclusión de Vj2-->bi2Vj1 a P’ ha utilizado la primera línea de nuestra construcción a partir
de Vj1-->bi2Vj2 en P, con Vj1S. No ha podido usarse la segunda línea pues en ese caso Vj2=S
lo que ya está descartado.
La inclusión de Vj1-->bi1 a P’ ha utilizado la cuarta línea de nuestra construcción a partir de
S-->bi1Vj1 en P. No ha podido usarse la tercera línea pues en ese caso Vj1=S lo que ya está
descartado.
Así pues, tenemos en P las producciones:
Vjk-->bik+1
Vjk-1-->bikVjk
...
Vj2-->bi3Vj3
Vj1-->bi2Vj2
S-->bi1Vj1
Donde ningún Vjh es S.
Luego, la siguiente derivación es posible en G:
S=>bi1Vj1=>bi1bi2Vj2=>bi1bi2bi3Vj3=>...=>bi1bi2bi3...bikVjk=>bi1bi2bi3...bikbik+1
Es decir, ũ L(G).
171
Ejemplo:
A partir de la GRLD G=({S,X},{a,b},P,S):
P:
S --> aX
X --> aX nótese que G no incluye a su símbolo raíz en
X --> bX la parte derecha de ninguna de sus producciones
X --> b
Construimos así G’=({S’,S,X},{a,b},P’,S’)
P’:
X --> a
X --> aX
X --> bX
S’ --> bX
Mostraremos el resultado con e.r. Si L es regular debe haber una e.r. r que la representa, es
decir, L(r)=L . El siguiente procedimiento parte de la e.r. r y construye la e.r. rR tal que
L(rR)=LR:
cuando r=: rR =
cuando r=: rR=
cuando r=a: rR=a
cuando r=t+s: rR=tR+sR
cuando r=t*: rR=(tR)*
cuando r=ts: rR=sRtR
172
r=ts: en este caso L=L(r)=L(t).L(s), y de ahí por definición de reversa LR=[L(s)]R.[L(t)]R. Por
nuestra construcción rR=sRtR, donde L(rR)=L(sR).L(tR), por hipótesis inductiva L(tR)=[L(t)]R
y L(sR)=[L(s)]R, es decir, L(rR)=[L(s)]R[L(t)]R.
r=t*: en este caso L=L(r)=[L(t)]* , y de ahí por definición de reversa LR=([L(t)]R)*. Por
nuestra construcción rR=[tR]*, donde L(rR)=[L(tR)]*, por hipótesis inductiva L(tR)=[L(t)]R, es
decir, L(rR)=([L(t)]R)*.
Ejemplo:
Sea L=L(r) con r=a(a+b)*b
rR=b(a+b)*a
173
Es decir, h respeta la concatenacion: h(xy) = h(x)h(y)
h(λ) = λ
Ejemplos:
Sean Σ = {a, b, c} y Γ = {0, 1}.
h(a) = 0
h(b) = 10
h(c) = 0
Para la cadena ab Σ*:
h(ab) = h(a)h(b)
= 010
Sea L = { 0n1n | n ≥ 0 }
h(0) = ab
h (1) = ba
Entonces:
h (L) = { (ab)n(ba)n | n ≥ 0 }
Se puede ver al homomorfismo como una operacion sobre e.r. Para la e.r r:
h(r) es la e.r. obtenida reemplazando cada ocurrencia de a (en r) por h(a).
Llamaremos r’ a h(r).
Ejemplo:
Para la e.r r = (a + b + c)*
h(a) = 0
h(b) = 10
h(c) = 0
h(a + b + c)*) = (0 + 10 + 0)* = (0 + 10)*
Σ = {a,b,c} Γ= {a,b,c}
L = L(b*ac*) (note que todo es en paralelo)
h(a) = abc
h(b) = bac
h(c) = cab
Entonces:
h(L) = L( (bac)*(abc)(cab)* ) Note el uso de paréntesis
5)
174
Sean Σ = {0,1} y Γ = {a,b}.
h(0) = ab
h(1) = λ
L = L(r) donde r = 01* + 10*
h(L) = abλ + λ(ab)*
*
note el uso correcto de paréntesis
* *
= ab + (ab) = (ab)
Demostración:
Dado que L es regular, existe una expresión regular r tal que L(r) = L.
Para demostrar que h(L) es regular construiremos recursivamente una expresión regular r’
a partir de r y luego probaremos que L(r’) = h(L):
Se construye r’, a partir de r, así:
Si r=∅ o r=λ, entonces r’=r
Si r=a , aΣ, entonces r’=(h(a))
Caso Base:
-r=λ
L = L(r) = { λ }
Entonces r' = h(r) = r = λ
Es evidente que L (r') = h(L)
-r=∅
L = L(r) = { }
Entonces r' = h(r) = r = ∅
Es evidente que L (r') = h(L)
175
- r = a.
L = L(r) = { a }
Entonces r' = h(r) = h(a)
L(r') = L(h(a)) = { h(a) } = h(L)
Hipótesis Inductiva:
El enunciado es cierto para e.r. con menos de n operadores.
El enunciado es cierto para estructuras menores.
Paso Inductivo:
Hay tres casos dependiendo de la forma de r:
1) r = r1 + r2 Sabemos que L = L(r) = L(r1) U L(r2)
r' = r'1 + r'2 = h(r1) + h(r2)
L(r') = L(r'1 + r'2) = L(r'1) U L(r'2) y por hipótesis inductiva:
= h(L(r1)) U h(L(r2))
= h(L(r1) U L(r2)) puesto que h se aplica a un lenguaje por
aplicacion a cada una de sus cadenas
individualmente:
= h(L)
2) r = r1∙r2 Sabemos que L = L(r) = L(r1) ∙L(r2)
r' = r'1∙r'2 = h(r1) ∙h(r2)
L(r') = L(r'1∙r'2) = L(r'1) ∙L(r'2) y por hipótesis inductiva:
= h(L(r1)) ∙h(L(r2))
= h(L(r1) ∙L(r2)) y como h se aplica a un lenguaje por
aplicacion a cada una de sus cadenas
individualmente:
= h(L)
3) r = r1* Sabemos que L = L(r) = L(r1*)
* *
r' = r'1 = h(r1)
L(r') = L(r'1*) = (L(r'1))* y por hipótesis inductiva
*
= [h(L(r1))] Y como h(L1UL2) = h(L1) U h(L2), h(L1L2) =
h(L1)h(L2), h(L*)=[h(L)]*
= h(L(r1)*)
= h(L(r))
= h(L)
Sea h un homomorfismo.
h: Σ→Γ*
Sea LΓ un lenguaje cuyo alfabeto es Γ (el alfabeto del lenguaje de salida de h).
h-1(LΓ) = { w Σ* / h(w) está en LΓ}
¿Qué cadena formada por símbolos de Σ, se convierte en alguna cadena de LΓ?
El conjunto de todas esas cadenas es h-1(LΓ)
176
Ejemplos:
Sean Σ = { 0,1 } y Γ = { a, b }
h(0) = aa
h(1) = aba
Sea LΓ = { abaaa }
h−1(LΓ) = { 10 }
Sean Σ = { 0,1 } y Γ = { a, b }
h(0) = aa
h(1) = aba
Sea LΓ = L(r) con r=(ab + ba)*a = {a, aba, baa, ababa, abbaa, baaba, babaa,...}
Para hallar h−1(LΓ), se trata de buscar las cadenas en Σ* a las cuales se les aplica el
homomorfismo h y están en L. Enumeremos algunos casos:
h(λ) = λ pero λLΓ
h(0) = aa pero aaLΓ
h(1) = aba aba LΓ
h(00) = aaaa pero aaaaLΓ
h(01) = aaaba pero aaabaLΓ
h(10) = abaaa pero abaaaLΓ
h(11) = abaaba pero abaabaLΓ
…
h−1(LΓ) = {1}
Nótese que: h(h (LΓ)) = h(1) = aba. Es decir: h(h−1(LΓ)) LΓ
−1
177
LΓ = (00+1)*
h−1(LΓ) = (ba)*
Es decir:
w es de la forma (ba)n -para algún n-
si y sólo si
h(w) está en LΓ.
En efecto:
Si w es de la forma (ba)n -para algún n-
Entonces h(w) = (1001) n, que evidentemente está en LΓ
Demostración:
Sea LΓ = T(A) con A=(K, Γ, δ, q0, F) un AFD.
Construimos el AF A’ tal que T(A’) = h−1(LΓ) así:
A’=(K, Σ, δ’, q0, F)
δ’:
δ’(qi,a) = δ*(qi,h(a))
178
Probaremos primero que:
δ’*(qi,w) = δ*(qi,h(w))
Por inducción sobre |w|.
Caso Base:
|w|=0, es decir, w=λ:
δ’*(qi,w) = δ’*(qi,λ) pues w=λ
= qi por definición
= δ*(qi,λ) por definición
= δ*(qi,h(λ)) pues h(λ)=λ
= δ*(qi,h(w)) pues w=λ
Paso Inductivo:
Sea |u|=k+1, es decir, u=wa con |w|=k
δ’*(qi,u) = δ’*(qi,wa) pues u=wa
= δ’(δ’*(qi,w),a) por definición
= δ’(δ (qi,h(w)),a)
*
por hipótesis inductiva
= δ*(δ*(qi,h(w)),h(a)) por construcción de δ’
= δ*(qi,h(w)·h(a)) por un resultado previo
= δ*(qi,h(wa)) pues h respeta la concatenación
= δ*(qi,h(u)) pues u=wa
Ejemplo:
Sea Σ = {a,b,c}, Γ = {0,1}
h(a) = 01
h(b) = 10
LΓ = L(r) con r = (00+1)*
179
A partir de ese autómata construimos otro que acepte el homomorfismo inverso como se
indica en la construcción:
Y obtenemos el lenguaje, por ejemplo con ayuda del Lema de Arden: (ba)*
O sea: h−1(L) = L(r’) con r’=(ba)*
HALF
Sea L un lenguaje regular. Se define la operación HALF así:
HALF(L) = LHALF = L1/2 = {u / uv L y |u|=|v| }
La idea es ir con una cadena hacia adelante desde q0 y, en paralelo, hacia atrás desde algún
estado final, hasta un estado de encuentro que señala la mitad de la cadena en consideración.
Ejemplo:
Sea el siguiente AFD A:
180
K’ = { q0’,
[q0,q0], [q0,q1], [q0,q2], [q0,q3], [q0,q4], [q0,q5],
[q1,q0], [q1,q1], [q1,q2], [q1,q3], [q1,q4], [q1,q5],
[q2,q0], [q2,q1], [q2,q2], [q2,q3], [q2,q4], [q2,q5],
[q3,q0], [q3,q1], [q3,q2], [q3,q3], [q3,q4], [q3,q5],
[q4,q0], [q4,q1], [q4,q2], [q4,q3], [q4,q4], [q4,q5],
[q5,q0], [q5,q1], [q5,q2], [q5,q3], [q5,q4], [q5,q5] }
d'( [q0,q4], a) = { [q1,q3] } d'( [q0,q4], b) = { [q5,q3] } d'( [q0,q4], c) = { [q5,q3] } d'( [q0,q4], d) = { [q5,q3] }
d'( [q0,q3], a) = { [q1,q2] } d'( [q0,q3], b) = { [q5,q2] } d'( [q0,q3], c) = { [q5,q2] } d'( [q0,q3], d) = { [q5,q2] }
d'( [q0,q2], a) = { [q1,q1] } d'( [q0,q2], b) = { [q5,q1] } d'( [q0,q2], c) = { [q5,q1] } d'( [q0,q2], d) = { [q5,q1] }
d'( [q0,q1], a) = { [q1,q0] } d'( [q0,q1], b) = { [q5,q0] } d'( [q0,q1], c) = { [q5,q0] } d'( [q0,q1], d) = { [q5,q0] }
d'( [q1,q4], a) = { [q5,q3] } d'( [q1,q4], b) = { [q2,q3] } d'( [q1,q4], c) = { [q5,q3] } d'( [q1,q4], d) = { [q5,q3] }
d'( [q1,q3], a) = { [q5,q2] } d'( [q1,q3], b) = { [q2,q2] } d'( [q1,q3], c) = { [q5,q2] } d'( [q1,q3], d) = { [q5,q2] }
d'( [q1,q2], a) = { [q5,q1] } d'( [q1,q2], b) = { [q2,q1] } d'( [q1,q2], c) = { [q5,q1] } d'( [q1,q2], d) = { [q5,q1] }
d'( [q1,q1], a) = { [q5,q0] } d'( [q1,q1], b) = { [q2,q0] } d'( [q1,q1], c) = { [q5,q0] } d'( [q1,q1], d) = { [q5,q0] }
181
d'( [q2,q5], a) = { [q5,q5], [q5,q4], [q5,q3], [q5,q2], [q5,q1], [q5,q0] }
d'( [q2,q5], b) = { [q5,q5], [q5,q4], [q5,q3], [q5,q2], [q5,q1], [q5,q0] }
d'( [q2,q5], c) = { [q3,q5], [q3,q4], [q3,q3], [q3,q2], [q3,q1], [q3,q0] }
d'( [q2,q5], d) = { [q5,q5], [q5,q4], [q5,q3], [q5,q2], [q5,q1], [q5,q0] }
d'( [q2,q4], a) = { [q5,q3] } d'( [q2,q4], b) = { [q5,q3] } d'( [q2,q4], c) = { [q3,q3] } d'( [q2,q4], d) = { [q5,q3] }
d'( [q2,q3], a) = { [q5,q2] } d'( [q2,q3], b) = { [q5,q2] } d'( [q2,q3], c) = { [q3,q2] } d'( [q2,q3], d) = { [q5,q2] }
d'( [q2,q2], a) = { [q5,q1] } d'( [q2,q2], b) = { [q5,q1] } d'( [q2,q2], c) = { [q3,q1] } d'( [q2,q2], d) = { [q5,q1] }
d'( [q2,q1], a) = { [q5,q0] } d'( [q2,q1], b) = { [q5,q0] } d'( [q2,q1], c) = { [q3,q0] } d'( [q2,q1], d) = { [q5,q0] }
d'( [q3,q4], a) = { [q5,q3] } d'( [q3,q4], b) = { [q5,q3] } d'( [q3,q4], c) = { [q5,q3] } d'( [q3,q4], d) = { [q4,q3] }
d'( [q3,q3], a) = { [q5,q2] } d'( [q3,q3], b) = { [q5,q2] } d'( [q3,q3], c) = { [q5,q2] } d'( [q3,q3], d) = { [q4,q2] }
d'( [q3,q2], a) = { [q5,q1] } d'( [q3,q2], b) = { [q5,q1] } d'( [q3,q2], c) = { [q5,q1] } d'( [q3,q2], d) = { [q4,q1] }
d'( [q3,q1], a) = { [q5,q0] } d'( [q3,q1], b) = { [q5,q0] } d'( [q3,q1], c) = { [q5,q0] } d'( [q3,q1], d) = { [q4,q0] }
d'( [q4,q4], a) = { [q5,q3] } d'( [q4,q4], b) = { [q5,q3] } d'( [q4,q4], c) = { [q5,q3] } d'( [q4,q4], d) = { [q5,q3] }
d'( [q4,q3], a) = { [q5,q2] } d'( [q4,q3], b) = { [q5,q2] } d'( [q4,q3], c) = { [q5,q2] } d'( [q4,q3], d) = { [q5,q2] }
d'( [q4,q2], a) = { [q5,q1] } d'( [q4,q2], b) = { [q5,q1] } d'( [q4,q2], c) = { [q5,q1] } d'( [q4,q2], d) = { [q5,q1] }
d'( [q4,q1], a) = { [q5,q0] } d'( [q4,q1], b) = { [q5,q0] } d'( [q4,q1], c) = { [q5,q0] } d'( [q4,q1], d) = { [q5,q0] }
d'(q0’,λ) = { [q0,q4] }
d'( [q0,q4], a) = { [q1,q3] }
d'( [q1,q3], b) = { [q2,q2] }
d'( [q0,q4], b) = d'( [q0,q4], c) = d'( [q0,q4], d) = { [q5,q3] }
d'( [q1,q3], a) = d'( [q1,q3], c) = d'( [q1,q3], d) = { [q5,q2] }
d'( [q2,q2], a) = d'( [q2,q2], b) = d'( [q2,q2], d) = { [q5,q1] }
d'( [q2,q2], c) = { [q3,q1] }
182
Nótese que si seguimos un camino por , digamos [q5,q3] ese nos lleva a [q5,q2] y ese a [q5,q1] y
ese a [q5,q0], mismo que no tiene arcos definidos (llegan al conjunto vacío).
Nos parece innecesario escribir las combinaciones que faltan por corresponder a estados
inalcanzables: (14 13 12 110; 124 23 22 21 20; 34 33 32 31 30).
183
CAPÍTULO 11. PROBLEMAS DE DECISIÓN: El caso regular
Siempre es posible describir un problema de manera que su respuesta sea una decisión por un
sí o por un no, estos problemas denominados de decisión pueden ser muchísimos aunque
usualmente se consideran únicamente aquellos catalogados como generales e importantes.
En este contexto, se dice que un problema es decidible si su respuesta correcta siempre puede
obtenerse siguiendo un algoritmo ya sea explícito o implícito en algún resultado teórico; es
imprescindible mencionar que hay problemas que no son decidibles, es decir, que –para
dichos problemas- no hay un algoritmo que nos permita decir siempre un sí o un no como
respuesta.
La selección de problemas no siempre es coincidente, nosotros veremos algunos de los más
comunes. Nótese que si resolvemos un problema para una de las abstracciones –autómatas
finitos, gramáticas o expresiones regulares- el mismo también es resoluble para las otras pues
podemos apelar a la respuesta inicial a través de las conversiones que conocemos.
184
Procedimiento COMPLETAR (se supone que se trabaja con Ij):
Para cada [A-->,k] Ij A--> P; (N T)*
añadir para cada [B-->A,i] Ik B-->A P; , (N T)*
[B-->A,i] a Ij
Ejemplo:
Sea la cadena de entrada u=a1a2a3=abc, y la GRLD G=({S,A,B,C,D},{a,b,c,d},P,S)
P:
S-->aB
B-->bC
C-->c
C-->cD
D-->d
I0: [S-->aB,0]
Ni PREDECIR ni COMPLETAR añaden nuevos ítemes
Ahora j=1 y a1=a, I1:
[S-->aB,0] añadido en ESCANEAR a partir de [S-->aB,0]
[B-->bC,1] añadido en PREDECIR a partir de [S-->aB,0] y B-->bC
No se pueden añadir más ítemes
Ahora j=2 y a2=b, I2:
[B-->bC,1] añadido en ESCANEAR a partir de [B-->bC,1]
[C-->c,2] añadido en PREDECIR a partir de [B-->bC,1] y C-->c
[C-->cD,2] añadido en PREDECIR a partir de [B-->bC,1] y C-->cD
No se pueden añadir más ítemes
185
Ahora j=3 y a3=c, I3:
[C-->c,2] añadido en ESCANEAR a partir de [C-->c,2]
[C-->cD,2] añadido en ESCANEAR a partir de [C-->cD,2]
[D-->d,3] añadido en PREDECIR a partir de [C-->cD,2] y D-->d
[B-->bC,1] añadido en COMPLETAR a partir de [C-->c,2] y [B-->bC,1] I2
[S-->aB,0] añadido en COMPLETAR a partir de [B-->bC,1] y [S-->aB,0] I1
No se pueden añadir más ítemes
Testear I3: como [S-->aB,0] I3 entonces la cadena u=abc está en L(G).
Una alternativa es construir el conjunto de estados desde los cuales se llega a un estado final,
incluidos los propios estados finales.
B0 = F
Bi+1 = Bi { qj / (qj,a) Bi , a }
Si Bi=Bi+1 entonces E=Bi
Otra alternativa es ir probando cadenas para ver si el AFD acepta cuando menos una de ellas.
Para hacer más sistemática la prueba se escogen las cadenas en orden léxico, es decir, primero
luego a1 luego a2 ... luego an, luego a1a1, etc.
Si hay una cadena que es aceptada T(A) no es vacío, en otro caso T(A) si es vacío.
Lo central en esta alternativa es tener un número finito de cadenas de prueba, de lo contrario
podríamos estar intentando con las infinitas cadenas de * lo que es una pésima idea.
Este conjunto finito de cadenas de prueba lo ofrece el lema de bombeo. En efecto, sea A un
AFD con |K|=n: T(A) u |u|<n (p1,u)F
Es obvio que si hay una cadena que llega a un estado final entonces T(A).
186
Inversamente, supongamos que T(A), probaremos que u |u|<n (p1,u)F por
reducción al absurdo.
Supongamos que la cadena más pequeña –en longitud- de T(A) es u, con |u|n-, por el lema
de bombeo podemos reescribirla así u=xyz con y, así pues xz no está en T(A), pues xz es
más pequeña que u y el supuesto es que u es la cadena más pequeña de T(A).
Por el lema de bombeo sabemos que i0 xyiz T(A) , de ahí es claro que xz está en T(A)
y, dado que |xz|<|xyz|, xz es aun más pequeña que u. Esta contradicción prueba el enunciado
que nos da el conjunto finito de cadenas de prueba buscado: debemos probar solamente las
cadenas de longitud menor que |K| si alguna de ellas, es aceptada es obvio que T(A), en
otro caso T(A)=.
187
l-equivalencia de AFD’s (el algoritmo de Moore)
El problema siguiente es decidible: ¿son iguales los lenguajes aceptados por A1 y A2?
En efecto, sean A1 y A2 dos AFD’s tales que L1=T(A1) y L2=T(A2), basta con testear los
siguiente que sabemos que si es decidible: L1L2 y L2L1, puesto que
L1=L2 L1L2 L2L1
Una alternativa es efectuar lo que se denomina la suma directa de AFD’s denotada por ⊕.
Sin pérdida de generalidad supondremos que el alfabeto de entrada es el mismo para A1 y A2.
A1⊕A2=A=(K1K2, , , q1 -ó p1-, F1F2)
: (ri,a) =i(ri,a) riKi
Luego, construimos la partición en clases de equivalencia de K=K1K2 inducida por la
relación E (como en la construcción del autómata mínimo), y vemos si los estados iniciales de
A1 y A2 están en la misma clase de equivalencia, si es así T(A1)=T(A2), en otro caso no.
Equivalencia de e.r
El problema siguiente es decidible: ¿son equivalentes las e.r. r1 y r2?
Sean L(r1), L(r2).
Construimos los AFD’s mínimos A1 y A2 tales que L(r1)=T(A1) y L(r2)=T(A2) ya vimos que
ello es posible. Luego basta con verificar que A1 y A2 son isomorfos.
O bien construimos los AFD’s A1 y A2 tales que L(r1)=T(A1) y L(r2)=T(A2), ya vimos que
ello es posible. Luego verificamos la l-equivalencia de estos AFD’s, es decir, si T(A1)=T(A2)
cosa que ya la sabemos decidible.
188
Para las marcas usaremos un “*” e indicaremos una fila cerrada con el subíndice x a la
izquierda de su entrada, tanto el marcado como el cierre de filas debe hacerse en orden,
primero la fila uno, luego la dos, etc.
Para cualquier fila, si alguna marca corresponde a una columna +, es decir, a un estado final,
en su última columna se anota ‘si’ (incluye ).
La primera fila tiene la entrada y se marcan todas las columnas correspondientes a los
estados iniciales, y luego todas las columnas correspondientes a los estados a los que se llegue
desde algún estado inicial con sólo -transiciones.
Si hay una fila no cerrada –digamos la fila i- con entrada w se añaden a filas con
entrada wa y se procede a cerrar la fila i.
Para una fila añadida que sólo tiene un dato en su columna entrada, se añaden marcas en todas
las columnas correspondientes a los estados a los que se llegue desde algún estado inicial con
su cadena de entrada incluyendo el uso de -transiciones (ello puede facilitarse observando
que la fila i, que ha dado lugar a esta fila añadida, ya tiene marcas con su cadena de entrada:
sólo resta ver a qué estados llegamos -con el símbolo a- de los estados correspondientes a
dichas marcas, incluyendo el uso de -transiciones, y marcarlos en la fila añadida).
Si una fila nueva -digamos la fila i- es exactamente igual a otra fila anterior -digamos la fila j-
en las columnas correspondientes a los estados (tiene las mismas marcas –o ninguna- en las
mismas posiciones), se cierra y se coloca la cadena de entrada de la fila j en la columna igual
a de la fila i (si la igualdad es con más de una fila anterior, se elige la primera).
Una vez que se termina de construir B para las e.r. r1 y r2, se comparan las filas de ambas
matrices correspondientes a las mismas entradas, pero sólo aquellas que tengan la columna
igual a en blanco: para cada una de estas filas, si en ambas matrices sus columnas incluye
están en blanco -o contienen ‘si’- ambas, las e.r. r1 y r2 son equivalentes, en otro caso no.
Es posible que las matrices B para r1 y r2 no tengan todas sus entradas en común, es decir, en
una matriz puede existir una entrada digamos w –con la columna igual a en blanco- y dicha
entrada puede no estar presente en la otra matriz (porque ya se cerraron todas sus filas), en
este caso se añade en la matriz ‘incompleta’ una fila con la entrada w faltante y cuyas otras
celdas se llenan copiando sus datos de una fila anterior según el siguiente criterio: con
seguridad hay otra(s) fila(s) que tiene(n) en su entrada una cadena que es prefijo de la entrada
w que falta, si hay más de una se elige la que tenga el prefijo más largo en longitud, esta fila
–con este prefijo más largo, digamos u tal que w=uv- debe tener su columna igual a no en
blanco sino con una cadena, a esta cadena se le concatena v, la fila que hay que copiar es la
que tiene en su entrada esta concatenación.
Ejemplos:
Sean las e.r. r1=(ab*)* y r2=+a(a+b)* ¿son equivalentes r1 y r2?
189
r1 : r2:
190
entrada p1 p2 p3 + igual a incluye
x * * si
x a * * si
x b
x aa * * a si
x ab * * a si
x ba b
x bb b
Ahora nos resta ver –de las filas que tienen en blanco la celda de la columna igual a, que son
aquellas con entrada , ‘a’ y ‘b’- si coinciden en la celdas incluye , en efecto es así pues
estas celdas –para dichas entradas- tienen los valores ‘si’, ‘si’ y en blanco respectivamente en
ambas matrices. Luego, r1 y r2 si son equivalentes.
Uno de los ejemplos clásicos de Ginzburg ofrece estas dos matrices. Para r1:
entrada p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 + igual a incluye
x *
x 0 *
x 1 * * * si
x 00 * 0
x 01 * *
x 10 *
x 11 * 0
x 010 * 0
x 011 * * * * si
x 0110 * * 01
x 0111 * 0
Para r2 (nótese que no tiene una entrada w=011):
entrada q1 q2 q3 q4 q5 + igual a incluye
x *
x 0 *
x 1 * * * si
x 00 * 0
x 01 *
x 10 *
x 11 * 0
Añadimos una fila con la entrada faltante cuyos demás datos se copian según lo indicado, en
este caso de la fila con entrada ‘1’; ello es así pues w=011=01.1=u.v, es decir, u=01 es el
prefijo más largo de w, prefijo que es entrada de la quinta fila y que tiene en su columna igual
a la cadena , misma que concatenada con v=1 nos devuelve .1=1, como dijimos la fila que
se copia es la que tiene en su entrada esta concatenación, es decir, la fila con entrada ‘1’:
x 011 * * * si
191
Nótese también que la tabla para r1 en la entrada 01 tiene la celda igual a en blanco (aunque
no ocurre esto en la tabla para r2) en este caso también hay que comparar esta fila.
Todo el proceso de comparación indica que r1 y r2 si son equivalentes.
Para finalizar indicaremos brevemente que este procedimiento se basa en el hecho siguiente,
supongamos que el alfabeto sobre el que se conforman las e.r. es {a1,...,an}:
r = a1.Da1(r) + ... + an.Dan(r) + (r)
es la función –ya conocida- que testea si L(r), y r es cualquier e.r. incluso una derivada.
Como puede hacerse lo mismo para otra e.r., es imaginable construir un sistema compuesto de
ecuaciones en e.r. como se simula con las matrices. Es claro que esta no es una descripción
completa de cómo trabaja y demuestra Ginzburg su procedimiento cosa que escapa al alcance
de este trabajo.
Lenguajes no regulares
El siguiente es un problema complejo: ¿es L un lenguaje regular?
En efecto, hay lenguajes que no son regulares, es decir, lenguajes para los cuales no es posible
escribir una gramática regular que los genere ni un autómata finito que los acepte.
El ejemplo típico es L={ajbj / j>0}, es imposible escribir una gramática que genere L o un
autómata que acepte L.
Conviene pues tener instrumentos que nos ayuden en la tarea de decidir si un lenguaje es o no
es regular y, sólo si es regular, empezar la tarea de escribir una gramática o un autómata para
ese lenguaje.
Sabemos que los conjuntos –de cadenas- finitos son regulares.
Dado un conjunto infinito de cadenas, el lema de bombeo puede ser útil para mostrar que no
es regular.
Ejemplos:
Mostraremos que L={ajbj / j>0} no es regular por reducción al absurdo.
Supongamos que sí lo es, es decir, hay un AFD A tal que T(A)=L, con |K|=n.
Es claro que L es infinito, luego hay una cadena uT(A) tal que |u|n, por ejemplo para j=n la
cadena u=anbn es tal que |u|=2nn, por el lema de bombeo u puede reescribirse así u=xyz, con
|xy|n, por lo tanto como y, dicha subcadena es del tipo y=ak con 1kn, pues los primeros
n símbolos de u son a’s y la subcadena y está entre estos primeros n símbolos; por el mismo
lema sabemos que i0 xyizT(A), es decir, i0 xyiz está en L; pero por simple
inspección es claro que las cadenas xyiz con i=2,3,4,etc., no están en L, puesto que tendrán
más a’s que b’s. Por ejemplo con i=2 xyiz=an+kbn. Esta contradicción indica que nuestro
supuesto es falso y que L no es regular.
A menudo este mismo hecho suele mostrarse así: es claro que L es infinito, luego hay una
cadena uT(A), tal que |u|n.
Por el lema de bombeo u puede reescribirse así u=xyz
¿Cómo son las cadenas x,y,z? Abarcaremos -genéricamente- todas las posibilidades:
1) x=aj, y=bj, z=
192
Por el lema de bombeo con i=2,3,4,etc., las cadenas xyiz están en T(A), es decir, en L.
Por simple inspección es claro que las cadenas xyiz i=2,3,4,etc., no están en L, puesto que
tendrán más b’s que a’s.
2) x= , y=aj, z=bj
Por el lema de bombeo con i=2,3,4,etc., las cadenas xyiz están en T(A), es decir, en L.
Por simple inspección es claro que las cadenas xyiz i=2,3,4,etc., no están en L, puesto que
tendrán más a’s que b’s.
3) x=aj-h, y=ahbk, z=bj-k
Por el lema de bombeo con i=2,3,4,etc., las cadenas xyiz están en T(A), es decir, en L.
Por simple inspección es claro que las cadenas xyiz i=2,3,4,etc., no están en L, puesto que al
incrementar i -ello es muy claro ya con i=2- obtenemos cadenas del tipo xahbk...ahbkz es decir
con a’s y b’s mezcladas.
Cualquier otra posibilidad será semejante a las ya vistas y su razonamiento es análogo.
Estas contradicciones -agotadas todas las posiblidades para x,y,z- muestran que nuestro
supuesto es falso y que L no es regular.
Mostraremos que L={aj / j un número primo} no es regular -nótese que las longitudes de las
cadenas de L son números primos-.
Supongamos que si lo es, es decir, hay un AFD A tal que T(A)=L, con |K|=n.
Se sabe que L es infinito, luego hay una cadena uT(A) -digamos u=aj- tal que |u|=jn, con j
un número primo, según el lema u puede reescribirse así u=xyz.
Es claro que, por la propiedad asociativa y conmutativa de la suma de longitudes,
|u| = |xyz| = |x|+|y|+|z| = |xz|+|y| = j, con j primo. Sea |y|=m (m>0 pues y).
Por el lema de bombeo sabemos que i0 xyizT(A), es decir, i0 xyiz está en L, es decir,
|xyiz| = |xz|+|yi| = |xz| + i |y| = |xz| + im es un número primo i0.
En particular, cuando i=0, |xz|=p es un número primo (es decir, p>1).
Por lo ya dicho, |xz| + im = p + im es un número primo i0, según el lema de bombeo.
Pero por simple inspección es claro que cuando i=p dicho número (p + pm) no es primo
puesto que es divisible por p (p1 y pp+pm, esto último porque p>1 y m>0).
Esta contradicción muestra que nuestro supuesto está equivocado y L no es regular.
2
Mostraremos que L={ a j / j2 un cuadrado perfecto} no es regular –nótese que las longitudes
de las cadenas de L son cuadrados perfectos-.
Supongamos que si lo es, es decir, hay un AFD A tal que T(A)=L, con |K|=n.
Es claro que L es infinito, luego hay una cadena uT(A) tal que |u|n, por ejemplo para j=n la
cadena u = a n es tal que |u|=n2n, por el lema de bombeo u puede reescribirse así u=xyz; por
2
el mismo lema i0 xyizT(A), en particular con i=2, xyyz está en L, es decir,
|xyyz| es un cuadrado perfecto. Además:
|u|=|xyz|=n2
Como |y||xy|, y como |xy|n –por el lema-, resulta que |y|n.
Como |xyyz|=|xyz|+|y|, como |xyz|=n2, y como |y|n, resulta que |xyyz|n2n
193
Como n2nn2n<n2n+1 y como n2n+1=(n+1)2, resulta que |xyyz|<(n+1)2
Como n2=|xyz|, y como |xyz|<|xyyz| -ya que |y|>0, pues y-, resulta que n2<|xyyz|.
De ahí, n2<|xyyz|<(n+1)2, es decir, xyyz es una cadena cuya longitud está entre dos cuadrados
perfectos consecutivos, es decir, su longitud no es un cuadrado perfecto, luego por simple
inspección xyyz no está en L.
Esta contradicción muestra que nuestro supuesto está equivocado y que L no es regular.
El teorema de Myhill-Nerode también puede usarse para mostrar que ciertos lenguajes no son
regulares. En efecto, dicho teorema dice que L es regular si y sólo si la relación RL tiene
índice finito. Así, mostrar que la relación RL tiene índice infinito –es decir tiene infinitas
clases de equivalencia- para un L dado, es lo mismo que mostrar que L no es regular.
Recuerde que dos cadenas x,y están en una misma clase de equivalencia en RL cuando
w xw L yw L.
Por lo mismo dos cadenas x,y no están relacionadas, es decir, están en diferentes clases de
equivalencia cuando w tal que sólo una de las cadenas xw,yw está en L y la otra no.
Este es el criterio que se utiliza: mostrar cadenas -infinitas- que sean distinguibles entre sí, es
decir, que estén en diferentes -infinitas- clases de equivalencia.
Ejemplos:
Mostraremos que L={ajbj / j>0} no es regular.
Sea [a]RL una clase de RL.
Obviamente aa[a]RL, pues con w=bb, abbL pero aabbL.
Sea [aa]RL otra clase de RL. Por razones semejantes aaa[a]RL y aaa[aa]RL, w=bbb sirve para
ver esto, sea [aaa]RL otra clase de RL.
Podemos extender el razonamiento recurrentemente e indicar la presencia de las siguientes
clases [a]RL, [aa]RL, [aaa]RL, [aaaa]RL, [aaaaa]RL, etc., es decir, RL tiene infinitas clases de
equivalencia, luego L no puede ser regular.
Otros resultados pueden utilizarse para mostrar que un lenguaje dado no es regular. El hecho
de que los lenguajes regulares sean cerrados respecto de la intersección por ejemplo.
Mostraremos que L1={ u{a,b} / Na(u)=Nb(u) } no es regular.
Supongamos que sí lo es. Sabemos también que L2={a}*.{b}* es regular.
194
Luego, por la cerradura indicada L=L1L2 también es regular. Pero L={ajbj / j>0} y ya
sabemos que L no es regular. Esta contradicción prueba el enunciado.
195
CAPÍTULO 12. TÓPICOS SOBRE LENGUAJES LIBRES DE CONTEXTO
Ejemplos:
Sea la GLC G=({S,Z},{0,$},P,S)
P:
S --> 0S0
S --> $Z
Z --> 0Z0
Z --> $
L = { 0j$0i$0j+i / i,j≥0 } = { 0j$0i$0i0j / i,j≥0 }
Para construir un AP que acepte L = { w / w{a,b}* & Na(w) < Nb(w) < 2·Na(w) },
en principio notemos que la cadena más pequeño es 2 “a’s” y 3 “b’s” (en cualquier orden).
Manejaremos ello así: la primera “a” debe exigir una “b” (antes o después de ella no importa);
la segunda “a” debe exigir dos “b’s” (antes o después de ella no importa).
Las reglas de transición son las siguientes.
:
(q0,a,Z)={ (q1,XZ) } primera “a” coloco una X (exigirá una “b”) (q1 significa que ya leí una “a”)
(q1,a,X)={ (q2,XXX) } segunda “a”(símbolo anterior “a”) coloco dos X’s (exigirá dos “b’s”)
(q1,b,X)={ (q1,) } con cada “b” saco una X
(q1,b,Z)={ (q1,YZ) } a no ser que aparezca Z:por cada b coloco una Y
(q1,b,Y)={ (q1,YY) } si siguen las “b’s”:por cada b coloco una Y
(q1,a,Y)={ (p,) } segunda “a” (símbolo anterior “b”) debo sacar dos “Y’s”
(p,,Y)={ (q2,) } aquí saco la segunda Y (ej. “abbba…”)
(p,,Z)={ (q2,XZ) } es posible que no hayan dos “Y’s” (ej. “abba…”).
Truco: exigir otra “b” colocando X
(q1,a,Z)={ (q2,XXZ) } segunda “a” (pero no hay “Y’s”) (ej. “baa…”)
Truco: exigir dos “b’s” colocando XX
(q0,b,Z)={ (q0,YZ) } la cadena empieza con “b’s”:por cada b coloco una Y
(q0,b,Y)={ (q0,YY) }
(q0,a,Y)={ (q1,) } primera “a” saco una Y (q1 significa que ya leí una “a”)
(q2,a,Z)={ (q2,XZ), (q2,XXZ) } por cada “a” coloco una o dos X’s
(q2,a,X)={ (q2,XX), (q2,XXX) }
(q2,b,X)={ (q2,) } con cada “b” saco una X
(q2,b,Z)={ (q2,YZ) } es posible que aparezca Z (ej. “aabbb-bba”) )
(q2,b,Y)={ (q2,YY) } por cada b coloco una Y
(q2,a,Y)={ (q2,), (p,) } con cada a saco una o dos Y’s
(q2,,Z)={ (q9,) }
(note que cadenas tipo “aabbb-bab” se manejan bien)
196
¿L=L(G)?
Sea la GLC G=({S},{a,b},P,S)
P:
S --> aSb
S --> ab
L={ajbj / j>0}
LL(G): Por inducción sobre la longitud de las cadenas en L (que genéricamente es 2j).
Caso Base: uL, |u|=2 con j=1, es decir, u=ab, por la segunda producción es claro que S=>ab,
es decir, uL(G).
Hipótesis Inductiva: sea uL con |u|=2k, entonces uL(G), es decir, S=>*u
Paso Inductivo: sea uL con |u|=2(k+1), es decir, |u|=2k+2, como u está en L, debe ser de la
forma allí indicada, es decir, podemos reescribir lícitamente esta cadena así u=aa kbkb=awb,
con |w|=2k además que wL. Por hipótesis inductiva S=>*w. Por otra parte, utilizando la
primera producción S=>aSb. Luego S=>aSb=>*awb, es decir, S=>*u, entonces uL(G).
Caso Base: uL(G) y se deriva en un paso, es decir, S=>u, ello sólo puede suceder si se
utiliza la segunda producción y u=ab, pero entonces uL (con j=1).
Hipótesis Inductiva: sea uL(G) generada en menos de k pasos de derivación, entonces uL.
Paso Inductivo: Sea uL(G) generada en k pasos de derivación. Por la forma de las
producciones podemos desglosar dicha derivación en su primer paso y el resto de los pasos:
S=>aSb=>*awb=u, pero entonces w deriva de S en menos de k pasos, por hipótesis inductiva
wL, luego es de la forma aibi (i>0) de donde u=aaibib=ajbj, con j=i+1 (j>0), luego uL.
LL(G): Por inducción sobre la longitud de las cadenas en L (que es un número par).
Caso Base: uL, |u|=2, es decir, u=ab ó u=ba, por la producción S --> ab es claro que S=>ab,
o bien por la producción S --> ba es claro que S=>ba, es decir, uL(G).
197
Hipótesis Inductiva: Sea uL con |u|<k, entonces uL(G), es decir, S=>*u
Paso Inductivo: Sea uL con |u|=k, como u está en L, debe ser de la forma allí indicada, es
decir, Na(u)=Nb(u); podemos reescribir lícitamente esta cadena de diversas formas: u=awb,
u=bwa, u=abw, u=baw, u=wab ó u=wba, en todas estas posibilidades |w|<k además que
Na(w)=Nb(w), es decir, wL, luego por hipótesis inductiva S=>*w. Pero entonces,
S=>aSb=>*awb, utilizando la producción S --> aSb en el primer paso, es decir, S=>*u; o bien
S=>bSa=>*bwa, utilizando la producción S --> bSa en el primer paso, es decir, S=>*u; o bien
S=>abS=>*abw, utilizando la producción S --> abS en el primer paso, es decir, S=>*u; o bien
S=>baS=>*baw, utilizando la producción S --> baS en el primer paso, es decir, S=>*u; o bien
S=>Sab=>*wab, utilizando la producción S --> Sab en el primer paso, es decir, S=>*u; o bien
S=>Sba=>*wba, utilizando la producción S --> Sba en el primer paso, es decir, S=>*u
Está claro que en todos estos casos S=>*u, luego uL(G).
Las otras formas de u (por ejemplo cuando empieza y termina con el mismo símbolo) siempre
pueden reescribirse así u=vw con vL, wL y |v|<k, |w|<k, por hipótesis inductiva S=>*v, así
como S=>*w, pero entonces S=>SS=>*vS=>*vw, utilizando la producción S --> SS en el
primer paso, es decir, S=>*u, luego uL(G).
Caso Base: uL(G) y se deriva en un paso, es decir, S=>u, ello sólo sucede si se utiliza la
producción S --> ab ó S --> ba con u=ab o u=ba, pero entonces uL con Na(u)=Nb(u)=1.
Hipótesis Inductiva: Sea uL(G) generada en menos de k pasos de derivación, entonces uL.
Paso Inductivo: Sea uL(G) generada en k pasos de derivación. Por la forma de las
producciones podemos desglosar dicha derivación en su primer paso y el resto de los pasos
así:
S=>SS=>*wS=>*wv=u, si utilizamos S --> SS en el primer paso; o bien
S=>aSb=>*bwa=u, si utilizamos S --> aSb en el primer paso; o bien
S=>bSa=>*bwa=u, si utilizamos S --> bSa en el primer paso; o bien
S=>abS=>*abw=u, si utilizamos S --> abS en el primer paso; o bien
S=>baS=>*baw=u, si utilizamos S --> baS en el primer paso; o bien
S=>Sab=>*wab=u, si utilizamos S --> Sab en el primer paso; o bien
S=>Sba=>*wba=u, si utilizamos S --> Sba en el primer paso;
pero en todos estos casos w deriva de S en menos de k pasos, luego por hipótesis inductiva
wL, es decir Na(w)=Nb(w), de donde Na(u)=Na(w)+1=Nb(w)+1=Nb(u), es decir, uL.
Si el primer paso se da utilizando S --> SS tenemos: S=>SS=>*wS=>*wv=u; pero aquí tanto w
como v derivan de S en menos de k pasos, luego por hipótesis inductiva w,vL, es decir
Na(w)=Nb(w) y Na(v)=Nb(v), de donde Na(u)=Na(w)+Na(v)= Nb(w)+Nb(v)=Nb(u), es decir,
uL.
198
Arboles de derivación y derivaciones
Sea G una GLC y sea A=>*u entonces hay un árbol de derivación A con producto u y cuya
raíz tiene la etiqueta A.
Demostración:
Por inducción sobre el número de pasos derivación.
Caso base: La derivación A=>*u se efectúa en un paso, es decir, A=>u. Pero entonces, la
producción A-->u está en P. Sea u=ej1...ejm, entonces el siguiente es un árbol de derivación
lícito con producto u y cuya raíz tiene la etiqueta A:
Sea A un árbol de derivación con etiqueta A en su raíz y con producto u, entonces hay (por lo
menos) una derivación A=>*u.
Demostración:
Por inducción sobre el número de nodos interiores de A.
199
Caso base: Hay sólo un nodo interior en A. Es decir, A es así:
Ejemplo:
Para P={S-->AX, X-->SA, S-->a, A-->a} y para la cadena ‘aaaaa’, su árbol de derivación es:
200
Donde la línea jaspeada indica un camino en el árbol, desde el nodo
raíz etiquetado con S hasta un nodo hoja que tiene la etiqueta
Terminal ‘a’.
Este camino se lo puede representar así: S-X-S-X-S-a, el cual
evidentemente tiene 6 nodos.
Hay otros caminos, por ejemplo S-A-a, que tiene 3 nodos.
Sin embargo, el camino jaspeado es el camino más largo, es decir el
que tiene más nodos, en este árbol de derivación.
En un árbol de derivación, no hay necesariamente un único camino
más largo. Por ejemplo en este árbol otro camino más largo es:
S-X-S-X-A-a, que también tiene 6 nodos.
En todo caso el(o los) camino(s) más largo(s) de este árbol tiene(n)
6 nodos.
En particular también se puede decir que en este camino más largo
–el jaspeado- la etiqueta X se repite dos veces, y la etiqueta S se
repite tres veces.
Sea G una GLC en FNCH, y A un árbol de derivación para la derivación A=>*w, con wT+.
Si A tiene k nodos en su camino más largo, entonces |w|2k-2.
Demostración:
Por inducción sobre el número de nodos del camino más largo en A.
Caso base: No puede haber un camino más largo con sólo un nodo que corresponda a una
cadena en T+. Así, en el caso base, si el camino más largo tiene k=2 nodos, eso corresponderá
a una derivación del tipo A=>b, utilizando alguna producción A-->b. Es claro que |b|22-2=20,
es decir, es cierto que |b|1.
Hipótesis inductiva: El enunciado sigue para k nodos o menos en el camino más largo de A.
Paso inductivo: Supongamos que A es un árbol de derivación para A=>*w con k+1 nodos en
su camino más largo. Como G está en FNCH, el símbolo raíz A debe tener dos hijos cuyas
etiquetas denominaremos D y E, que son, a su vez, raíces de dos subárboles D y E
respectivamente, lo cual podemos graficar ‘en abstracto’ así:
201
Uno de los (sub)árboles –digamos el de u- tiene k nodos en su camino más largo (pues el
árbol para w tiene k+1 nodos en su camino más largo), luego -por hipótesis inductiva- |u|2k-2;
el otro (sub)árbol tiene k’ nodos en su camino más largo con k’k, luego |v|2k’-22k-2. Es
decir, |w|=|u||v| 2k-2 +2k-2=2k-1=2(k+1)-2, es decir, |w|2(k+1)-2, que demuestra lo indicado.
Cuando la GLC G no está en FNCH una forma análoga de trabajar es considerar al árbol
como m-ario, donde m es el máximo de número de hijos de los nodos.
Poda y expansión
Sea G una GLC y A un árbol de derivación para A=>*w.
Si A tiene algún camino en el que dos nodos de dicho camino –llamémosles ni y nj con i<j, es
decir, con nj descendiente de ni- tienen la misma etiqueta X, entonces los subárboles con
nodos raíz ni y nj respectivamente son, como ya se sabe, árboles de derivación en sí mismos a
los que denominaremos Ai y Aj.
La operación de poda consiste en reemplazar Aj en el nodo ni de A.
La operación de expansión consiste en reemplazar Ai en el nodo nj de A.
El árbol A ‘en abstracto’, Poda de A Expansión de A
se han señalado los nodos
ni y n j
202
ii) w=ytz con y,z(N T)*; y es la subcadena (a la izquierda del producto de Ai) que es la
primera parte del producto de A; z es la subcadena (a la derecha del producto de Ai) que es la
última parte del producto de A; la parte central es obviamente t.
iii) w=yuxvz.
El producto del árbol podado es yxz; el producto del árbol expandido es yuuxvvz.
Nótese que si la GLC G está limpia, entonces no hay producciones renombradoras y por tanto
u,v no pueden ser ambas la cadena vacía y por lo tanto |yxz|<|yuxvz|.
Pero si ni es el nodo raíz de A entonces y,z son ambas la cadena vacía pues A=Ai y w=t.
Lema de bombeo
Sea G una GLC, con |N|=n, limpia y en FNCH. Si wL(G) con |w|2n entonces
i) w = yuxvz w puede descomponerse en cinco subcadenas
203
ii) |uv| > 0 u y v no son simultáneamente la cadena vacía
iii) |uxv| 2n
iv) yuixviz L(G) para todo i0
Demostración:
Sea wL(G) con |w|2n, entonces el árbol de derivación A para S=>*w tiene en su camino más
largo n+2 nodos ó más. En efecto, si dicho árbol tuviera n+1 nodos (o menos) en su camino
más largo, entonces por el resultado de arriba con k=n+1 (o menos), |w|2n+1-2, es decir,
|w|2n-1 lo que no coincide con nuestro supuesto de que |w|2n.
Así pues, A tiene en su camino más largo por lo menos n+2 nodos. Lo que quiere decir que:
a) El último nodo de ese camino más largo es una hoja y tiene como etiqueta un Terminal.
b) Hay n+1 nodos (o más) -antes del último nodo en ese camino más largo- etiquetados con
No Terminales. Pero como sólo hay n No Terminales entonces alguna etiqueta X se repite.
Recogiendo los resultados vistos en poda y expansión (con A=S):
i) La cadena w puede reescribirse como w=yuxvz, una secuencia de 5 subcadenas (y,u,x,v,z).
ii) Como G está limpia, entonces u,v no pueden ser ambas la cadena vacía, es decir |uv|>0.
iii) Podemos suponer sin pérdida de generalidad que el subárbol que empieza en la primera
aparición de X (con producto t=uxv) tiene los últimos n+2 nodos del camino más largo de A,
esto es suficiente para que exista la repetición de la etiqueta X pues –sin contar el nodo hoja-
sólo hay |N|=n No Terminales para los n+1 nodos restantes; este supuesto es posible porque el
árbol A tiene -en su camino más largo- n+2 nodos o más: luego, por el resultado para la
longitud del producto en un camino más largo, |uxv|2(n+2)-2, es decir, |uxv|2n.
iv) La derivación de w=yuxvz a partir de S se puede representar legítimamente así:
S=>*yXz=>*yuXvz=>*yuxvz
Donde se han usado las dos derivaciones lícitas:
a) X=>*t que la hemos desglosado como X=>*uXv=>*uxv
b) X=>*x
Pero entonces también es posible derivar S=>*yXz=>*yxz (es decir, la poda de A).
Y también, S=>*yXz=>*yuXvz=>*yuuXvvz=>*yuuxvvz (es decir, la expansión de A).
Pero se puede expandir la expansión de A, es decir:
S=>*yXz=>*yuXvz=>*yuuXvvz=>*yuuuXvvvz=>yuuuxvvvz también se puede derivar.
Y así sucesivamente muchas veces, de manera que se puede derivar en general:
S=>*yuiXviz=>yuixviz, es decir, yuixviz L(G) para todo i0.
Algunas veces este lema se enuncia así:
Sea la GLC G, con |N|=n y limpia. Existe un entero e tal que si wL(G) con |w|e entonces
i) w = yuxvz w puede descomponerse en cinco subcadenas
ii) |uv| > 0 u y v no son simultáneamente la cadena vacía
iii) |uxv| e
iv) yuixviz L(G) para todo i0
La demostración es la misma suponiendo –sin pérdida de generalidad- que G está en FNCH y
haciendo e=2n.
204
El lema de Ogden
Es una versión más fuerte que el lema de bombeo; en vez de trabajar con toda la cadena w,
limita nuestro foco de atención a alguna porción que marcamos de w (por ejemplo en la
cadena w=aaabbccdd la parte marcada está en negrita).
Sea la GLC G, con |N|=n y limpia. Existe un entero e tal que si wL(G) y marcamos por lo
menos e símbolos de w entonces
i) w = yuxvz w puede descomponerse en cinco subcadenas
ii) x contiene algún símbolo marcado
iii) u y v no son simultáneamente libres de símbolos marcados (u.v tiene por lo menos uno)
iv) uxv tiene a lo máse símbolos marcados
v) yuixviz L(G) para todo i0
Demostración:
Supongamos –sin pérdida de generalidad- que G está en FNCH, hagamos e=2n+1 y para
wL(G) marquemos e símbolos de w. Sea A el árbol de derivación para S=>*w.
Basaremos todo en la noción de nodo-r. Un nodo-r (nodo de ramificación) es aquel cuyos dos
hijos tienen símbolos marcados en sus productos.
Construiremos un camino-r (es decir, un camino donde se señalan los nodos-r) empezando
con un nodo interior cualquiera así:
Sea n el último nodo añadido al camino-r.
Proceso:
Si n es hoja, terminamos.
Si n tiene dos hijos ni,nj los cuales tienen –ambos- símbolos marcados en sus productos,
señálese a n como nodo-r y añádase al camino-r el hijo con el mayor número de símbolos
marcados en su producto –digamos nj-. Repítase el proceso con nj.
Si n tiene dos hijos ni,nj de los cuales sólo uno de ellos tiene por lo menos un símbolo
marcado en su producto -digamos ni-, añádase ni al camino (nótese que no se señala a ni como
nodo-r). Repítase el proceso con ni.
Denotaremos a un camino-r poniendo en secuencia sus nodos así ni1-...-nih., donde se suponen
señalados los nodos-r.
Como resultado trabajaremos con caminos-r que incluyen nodos-r y probaremos que si un
camino-r construido como se indica arriba contiene q nodos-r entonces ni1 tiene a lo más 2q
símbolos marcados en su producto.
Demostración:
Por inducción sobre el número de nodos-r del camino-r.
Caso base: El camino-r tiene (q=)1 nodo-r. Llamemos nk a dicho nodo-r. Es claro que todos
los descendientes (hijos, nietos, etc.) de nk no son nodos-r.
Para ser un nodo-r, los dos hijos de nk tienen por lo menos un símbolo marcado en sus
productos, es decir, hay por lo menos 2=21=2q símbolo marcados.
No pueden haber más símbolo marcados, si ello sucediera uno de los hijos de nk tendría no
uno sino por los menos dos símbolos marcados en su producto, estos dos símbolos marcados
tendrían que estar en dos nodos hoja, como el árbol es binario estos dos nodos hoja deben
tener un ascendiente (padre, abuelo, etc.) en común (descendiente de nk), que por lo tanto
205
debería ser un nodo-r, pero sólo hay un nodo-r que es nk. Luego, hay a lo más 2q símbolos
marcados.
Hipótesis inductiva: El enunciado es cierto cuando el camino-r tiene q nodos-r.
Paso inductivo: Sea que el camino-r ni1-ni2-...-nih tiene q+1 nodos-r. Hay dos posibilidades,
que ni1 sea un nodo-r o no lo sea.
a) Si ni1 es un nodo-r, entonces hay q nodos-r en el camino ni2-...-nih, por hipótesis inductiva el
producto del subárbol con raíz en ni2 tiene a los más 2q símbolo marcados. Pero ni2 fue elegido
(al señalar ni1 como nodo-r) porque tiene el mayor número de símbolos marcados en su
producto; ni2 es uno de los dos hijos de ni1, por lo tanto el otro hijo de ni1 tiene –igualmente- a
lo más 2q símbolo marcados en su producto. Luego ni1 tiene a lo más 2q+2q=2q+1 símbolos
marcados en su producto.
b) Si ni1 no es un nodo-r, entonces trabajamos con ni2, nótese que el otro hijo de ni1 no tiene
–de acuerdo a nuestra construcción- símbolos marcados en su producto; si ni2 no es un nodo-r,
entonces trabajamos con ni3, etc., hasta tener un nodo-r nij, luego realizamos un razonamiento
análogo al inciso b, con ni(j+1) en lugar de ni2.
Lo que prueba el resultado previo. Continuemos con el lema de Ogden:
Recuerde que A es el árbol de derivación para S=>*w y que se marcan e=2n+1 símbolos de w.
Si construimos un camino-r cuyo primer nodo es el nodo raíz etiquetado con S hasta un nodo
hoja en A y denotamos a dicho camino por ni1-ni2-...-nih, dicho camino-r debe tener por lo
menos n+1 nodos-r, pues si tuviera n nodos-r o menos, por el resultado anterior, el producto w
de ni1 tendría a lo más 2n símbolos marcados, lo que no coincide con nuestro supuesto.
Así pues en ese camino-r con n+1 nodos-r y con sólo |N|=n No Terminales alguna etiqueta X
se repite.
Elijamos exactamente n+1 nodos-r (de dicho camino) lo más abajo posible, por ejemplo de
una hoja marcada hacia arriba. Sea ni el nodo-r con la primera aparición de X, y sea nj el
nodo-r con la segunda aparición de X, luego todo el tratamiento visto en el lema de bombeo
puede repetirse aquí básicamente. Es decir,
i) w = yuxvz w puede descomponerse en cinco subcadenas
El producto de nj es x. El producto de ni es uxv.
ii) Dado que nj es un nodo-r, su producto x contiene algún símbolo marcado.
iii) Sabemos que ni es un nodo-r, que nj es un nodo-r descendiente de ni y que el producto de
ni es uxv. Como ni es un nodo-r sus dos hijos tienen símbolos marcados en sus productos,
digamos que su hijo izquierdo ha sido elegido para ser parte del camino-r, en este caso su hijo
derecho tiene un producto que es parte de v, que –por lo dicho- tiene símbolos marcados. Si su
hijo derecho es el elegido entonces u tiene símbolos marcados. Luego,
u y v no son simultáneamente libres de símbolos marcados.
iv) Hemos elegido los n+1 nodos-r lo más abajo posible, luego el camino-r que empieza en ni
(cuyo producto es uxv) que tiene n+1 nodos-r, por el resultado previo, tiene a lo más 2n+1
símbolos marcados. Es decir, uxv tiene a lo máse símbolos marcados.
v) La derivación de w=yuxvz a partir de S se puede representar legítimamente así:
S=>*yXz=>*yuXvz=>*yuxvz, donde se han usado las dos derivaciones lícitas:
a) X=>*uXv=>*uxv, b) X=>*x , luego yuixviz L(G) para todo i0.
206
Clausura reflexiva transitiva con los movimientos
Lo que llamamos un movimiento no es sino el establecimiento de una relación denotada por
|-- y lo que hemos llamando resumen no es otra cosa que la clausura reflexiva transitiva de |--,
lo que se denota por |--*; por este motivo -debido a la identidad de la clausura reflexiva
transitiva- siempre es posible escribir que (qi,w,) |--* (qi,w,) para cualquier d.i. (qi,w,).
Sin embargo, probaremos que no existe ningún APe.f. Determinístico que acepte L.
Demostración:
Supongamos que sí existe un APe.f. Determinístico A1=(K1,{a,b},,1,q0,Z,F1) tal que
T(A1)=L con K1={q0,...,qm}.
Construimos otro APe.f. A2=(K2,{a,b},,2,p0,Z,F2) tal que T(A2)=L con K2={p0,...,pm}.
La idea es que A2 sea un clon de A1 difiriendo solamente en los nombres de los estados.
A partir de A1 y A2 construiremos otro APe.f. A así.
El conjunto de estados de A es (K1K2).
El estado inicial de A es q0.
El conjunto de estados finales de A es F2.
El alfabeto de A es {a,b,c}.
Es claro que tanto en 1 como en 2 cada regla tiene a lo más un par de llegada, pues A1 y A2
son determinísticos.
Las reglas de transición de A prácticamente se copian de 1 y 2 –obviamente quitando el
subíndice- con los siguientes cambios:
i) Si 1(qi,d,X)={(qj,)} está en 1 -con qiF1, d{a,b,}, X- se elimina (qj,) y en su
lugar colocamos(pj,), es decir, añadimos (qi,d,X)={(pj,)} a .
ii) Si 2(pi,b,X)={(pj,)} está en 2 -con piK2, X- en lugar de dicha regla añadimos
(pi,c,X)= {(pj,)}, es decir, las reglas con ‘b’ de A2 se copian colocando en lugar de ‘b’ el
símbolo ‘c’.
iii) Todas las otras reglas de 1 y 2 se copian.
Una vez que tenemos las reglas de efectuamos –en - el siguiente cambio:
iv) Si (ri,b,X)={(pj,)} está en -con ri(K1K2), pjK2, X- se elimina dicha regla y en
su lugar colocamos (ri,c,X)={(pj,)}. Nótese que primero debe seguirse el inciso i, mismo
que influye en este inciso iv.
207
Analicemos qué hace este nuevo APe.f. A:
Se sabe que A1 acepta {aibi / i>0}{aib2i / i>0}, en particular acepta cadenas en {aibi / i>0}.
Al aceptar una cadena del tipo aibi, A1 siempre acaba en el mismo estado final, pues es
determinista.
Se sabe que A2 acepta {aibi / i>0}{aib2i / i>0}, en particular acepta cadenas en {aib2i / i>0}.
Si en la cinta de entrada de A está una cadena w=aibici, en principio se comportará como A1 y
luego de consumir la subcadena aibi de w (está en negrita para que se note) el autómata A
estará en un estado qi que era de aceptación en A1 (qiF1) pues A1 acepta cadenas del tipo aibi;
a partir de ahí, por el inciso i primero y por el inciso iv luego, con la primera ‘c’ el autómata A
irá a un estado que era de A2, luego se comportará como A2 –con la novedad que las b’s ahora
están cambiadas por c’s- y, como A2 acepta cadenas del tipo aib2i, terminará consumiendo las
últimas c’s de w y aceptando esta cadena.
Por otro lado, A no puede aceptar otras cadenas que no sean del tipo aibici pues para ir de la
parte que era A1 a la parte que es A2 (que tiene los estados finales) debemos situarnos en un
estado que era final en A1, eso sólo sucede si contamos con una subcadena inicial tipo aibi;
luego –por el inciso i- necesariamente vamos a la parte que era A2, pero eso sucede sólo con el
símbolo ‘b’ cambiado por ‘c’ por el inciso iv, una vez ahí, para aceptar alguna cadena la parte
que era A2 requiere tantas c’s como sean necesarias para alcanzar un tipo de cadena semejante
a aibici, pues A2 es clon de A1, es decir acepta cadenas del tipo aib2i=aibibi que con las b’s
cambiadas por c’s resultan en aibici.
Es decir, A es tal que T(A)={aibici / i>0}, luego este lenguaje es libre de contexto. Pero al final
del subsiguiente capítulo probaremos que este lenguaje no es libre de contexto. Esta
contradicción muestra que nuestro supuesto está equivocado y que no hay ningún APe.f.
Determinístico que acepte L={aibi / i>0}{aib2i / i>0}.
En el siguiente capítulo veremos que si no hay un APe.f. Determinístico que acepte L,
entonces tampoco hay un AP Determinístico que acepte L.
208
Z-->A S2-->C
Z-->B S2-->BC
A-->aA C-->cC
A-->a C-->c
B-->Bb
B-->b
Sin embargo, probaremos que no existe ningún APe.f. Determinístico que acepte L1.
Demostración:
Supongamos que sí existe un APe.f. Determinístico A1=(K1,{a,b,c},,1,q0,Z,F1) tal que
T(A1)=L1.
Denominaremos L2 al complemento de L1, luego L2 es libre de contexto determinístico.
Se sabe que L3={aibjck / i,j,k0 } es regular (la e.r. r=aa*bb*cc* es tal que L(r)=L3).
Luego, L=(L2 L3) es un lenguaje libre de contexto.
Pero qué es L. El complemento de L1 puede caracterizarse así,
L2 = {aibjck / i=j i=k}R = {aibici / i0}R, donde R contiene el resto de las cadenas de L2,
por ejemplo las que empiecen con ‘c’, etc.
L=(L3 L2)={aibjck / i,j,k0} ({aibici / i0}R)={aibici / i>0} que como dijimos resulta libre
de contexto. Pero al final del subsiguiente capítulo probaremos que este lenguaje no es libre
de contexto. Esta contradicción muestra que nuestro supuesto está equivocado y que no hay
ningún APe.f. Determinístico que acepte {aibjck / ij ik}.
Ya dijimos que si no hay un APe.f. Determinístico que acepte L1, entonces tampoco hay un
AP Determinístico que acepte L1.
209
CAPÍTULO 13. CONVERSIONES GENÉRICAS: el caso libre de contexto
Construcción de una GLC limpia a partir de otra GLC cualquiera: limpieza de GLC’s
Si se trabaja con la GLC G tal que L(G)= -cosa que se puede decidir como veremos en el
próximo capítulo-, entonces el resultado de limpiar G será una especial GLC canónica
G’={{S},{a},{S-->aS},S} que es tal que L(G’)=. Si bien S es inútil en esta GLC,
recurriremos a esta convención.
i) Eliminación de producciones renombradoras (A-->B):
Sea G una GLC tal que L(G), entonces es posible construir otra GLC G’ tal que G’ no
tenga producciones renombradoras y L(G)=L(G’).
Demostración:
Sea la GLC G=(N,T,P,S) cuyos |N|=n No Terminales representaremos por V1,...,Vn.
A partir de G hacemos lo siguiente para construir la GLC G’=(N,T,P’,S) (no tomamos en
cuenta producciones del tipo B-->B que se eliminan directamente):
a) P0={ Vi-->/ Vi-->P y N }
Inicialmente incluimos en P0 todas las producciones de P que no son renombradoras.
b) Para i=1,...,n
DerivadeVi = { VjN / VjVi y Vi=>*Vj en P}
Pi = Pi-1 { Vi-->/ VjDerivadeVi y Vj-->Pi-1 }
c) P’ = Pn
Es claro que las producciones en P’no son producciones renombradoras.
Sea wL(G’), es decir, S=>*w con producciones de P’, sea 1Vi2=>12 un paso
cualquiera de esta derivación dado con la producción Vi--> de P’, 1,2(NT)*.
Por un lado, si esta producción se ha añadido a P’ en el inciso a) es que está en P, es decir, se
puede dar este paso en G.
Por otro lado, si esta producción se ha añadido a P’ en el inciso b) es que Vi=>*Vj en P y
Vj-->Pi-1 para algún i, es decir 1Vi2=>*1Vj2=>12, salvo posiblemente el último
paso todos los demás pueden hacerse en P, si Vj--> ha sido añadido en el inciso b) este
razonamiento se repite recurrentemente de manera que 1Vi2=>*12 puede hacerse en P.
Es decir cada paso de S=>*w en P’, puede hacerse o simularse en P, es decir, S=>*w también
en P, luego wL(G).
Sea wL(G) y sea A el árbol de derivación con etiqueta S en su raíz y con producto w,
sabemos que si efectuamos una derivación más a la izquierda entonces la derivación S=>*w es
única. Desglosemos esta derivación más a la izquierda en su último paso y el resto de ellos
S=>*yViz=>yz=w, con Vi-->P, z(N T)*, yT*, sin pérdida de generalidad
supondremos que el último paso no utiliza una producción renombradora (puesto que wT*).
Un derivación más la izquierda -efectuada con producciones de P- que empiece en S y derive
una cadena u(N T)* -no necesariamente de sólo Terminales, pero también éstas- cuyo
último paso no utilice una producción renombradora se puede hacer o simular con
producciones de P’.
210
Demostración:
Por inducción sobre el número de pasos de la derivación.
Caso base: Un paso de derivación, es decir S=>u donde se ha utlizado S-->uP que no es
renombradora, pero entonces esta producción se añade a P’ en P0, luego S=>u también en P’.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea S=>*u una derivación más a la izquierda con producciones de P efectuada
en k pasos, misma que puede desglosarse así S=>*yViz=>yz=u, con Vi-->P, z(N T)*,
yT*, el último paso no utiliza una producción renombradora.
Qué pasa con la primera parte de esta derivación, es decir, con S=>*yViz.
Una posibilidad es que todos sus pasos se hayan dado utilizando producciones renombradoras,
en cuyo caso y=z=, u= lo que hace que esta parte de la derivación sea así
S=>*Vi y toda la derivación de la cadena u sea así S=>*Vi=>, recordemos que el último paso
utiliza Vi-->P no renombradora y por tanto añadida a P’ en P0, pero entonces como
ViDerivadeS, S-->Ph para algún h, es decir, S-->P’, luego S=>u en P’.
Otra posibilidad es que la derivación más a la izquierda S=>*yViz incluya pasos de derivación
(pueden ser muchos, todos o sólo uno) que utilicen producciones no renombradoras.
Consideremos el último paso de derivación que utiliza una producción no renombradora en
S=>*yViz, dicho paso de derivación obtiene la cadena yVjz, es decir, S=>*yVjz=>*yViz,
puesto que yVjz aparece en el último paso de derivación que utiliza una producción no
renombradora, el resto de los pasos (de yVjz=>*yViz) utiliza sólo producciones
renombradoras.
Por hipótesis inductiva S=>*yVjz puede hacerse o simularse en P’.
Si Vj=Vi, como Vi-->P es no renombradora y por tanto añadida a P’ en P0, entonces
S=>*yViz=>yz puede hacerse o simularse en P’.
Si VjVi, es claro que ViDerivadeVj, como Vi-->P es no renombradora, entonces por el
inciso b), Vj-->Ph para algún h, es decir Vj-->P’, luego S=>*yVjz=>yz puede hacerse o
simularse en P’.
Todo ello muestra que S=>*w puede hacerse o simularse en P’, es decir, wL(G’).
Puede obtenerse el conjunto DerivadeVi a través de un grafo de dependencias en una GLC que
es una forma de ver las conexiones entre los No Terminales, para construirlo se forman tantos
nodos como No Terminales haya, y se grafica un arco –sin etiqueta- del nodo Vi al nodo Vj si
y sólo si hay una producción de la forma Vi-->uVjv, donde u y v son cualquier cadena en
(N T)*. Una variante útil a nuestro propósito es dibujar el grafo de dependencias que resulte
de tomar en cuenta sólo las producciones renombradoras. Con ayuda de este último grafo de
dependencias, Vi=>*Vj si en el grafo hay un camino de Vi a Vj.
211
Ejemplo:
Sea la GLC G=({S,A,B,C},{a,b},P,S)
P:
S-->A B-->aBb
A-->B C-->ab
B-->C
C-->S
El grafo de dependencias considerando sólo las producciones renombradoras es así:
212
Demostración:
Sea la GLC G=(N,T,P,S), identificaremos todos sus No terminales útiles -y por lo tanto sus
inútiles- así:
0 = T
UTIL0 = {}
UTILi+1 = UTILi {X / X -->P y i*} (para i=0,1,...)
i+1 = i UTILi+1 (fíjese bien los subíndices)
Si UTILi=UTILi+1 entonces UTILES=UTILi, INUTILES=(N-UTILES).
0 es de sólo Terminales pero los restantes 1, 2, etc., incluyen -posiblemente- Terminales y
No Terminales. Hay quienes en vez de exigir que i* piden que todos los No Terminales de
estén en UTILi, para el efecto es lo mismo. Es claro que algún momento se cumple la
condición -incluso añadiendo un No Terminal a la vez- pues N es finito.
A partir de G hacemos lo siguiente para construir la GLC G’=(N’=UTILES,T,P’,S).
Se construye P’ eliminando de P todas las producciones en las que aparezcan -donde fuere-
los No Terminales inútiles.
Debemos mostrar que A=>*w con wT* si y sólo si AUTILES.
Mostramos que si A=>*w entonces AUTILES por inducción sobre el número de pasos de
derivación (es obvio que si A está en algún UTILi está en UTILES).
Caso base: A=>w con wT* en un paso, es decir, A-->wP con wT*=0*, luego A está en
UTIL1, es decir, AUTILES.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que A=>*w con wT* en k pasos de derivación. Podemos desglosar esta
derivación así A=>ej1...ejm=>*w1...wm donde A-->ej1...ejmP, eji=>*wi, w=w1...wm.
Si eji es un Terminal entonces eji=wi (y eji=>*wi es cierto por la reflexividad de =>*).
Si eji es un No Terminal entonces eji=>*wi se hace en menos de k pasos, por hipótesis
inductiva ejiUTILES, pero entonces todos estos No Terminales están en algún h, luego
ej1...ejmh* y por tanto A está en UTILh+1, es decir, AUTILES.
El hecho de que si AUTILES entonces A=>*w sigue de la forma indicada de construir este
conjunto (aunque puede pensarse una inducción sobre i para UTILi pues UTILES no es más
que la reunión de todos estos conjuntos UTILi).
213
Ejemplo:
Sea la GLC G=({S,B,C},{a},P,S)
P:
S-->aBa S-->BC
B-->a C-->aC
0={a}
UTIL0={}
UTIL1={} {B}={B}
1={a,B}
UTIL2={B} {S,B}={B,S}
2={a,B,S}
UTIL3={B,S} {S,B}={B,S}
3={a,B,S}
Como UTIL2=UTIL3 entonces N’=UTILES={B,S }, INUTILES={C}
Se construye así la GLC G’=({S,B},{a},{S-->aBa,B-->a},S)
214
Mostramos que si S=>*yejz con y,z(N T)*, ejentonces ejACCESIBLES por
inducción sobre el número de pasos de derivación (es obvio que si ej está en algún Zi está en
ACCESIBLES).
Caso base: S=>*yejz en un paso, es decir, S--> yejzP, luego ej está en Z1, es decir,
ejACCESIBLES.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que S=>*yejz en k pasos de derivación. Podemos desglosar esta
derivación así S=>*uAw=>uy’ejz’w donde y=uy’, z=z’w, u,w,y’,z’(N T)*, A-->y’ejz’P.
Como S=>*uAw se hace en menos de k pasos, por hipótesis inductiva A está en está en algún
Zh (AACCESIBLES, así como todos los símbolos de u,w), además como A-->y’ejz’P,
resulta que ej está en Zh+1, es decir, ejACCESIBLES (así como todos los símbolos de y’,z’).
El hecho de que si ejACCESIBLES entonces S=>*yejz sigue de la forma indicada de
construir este conjunto (aunque puede pensarse una inducción sobre i para Zi pues los
Terminales accesibles y los No Terminales ACCESIBLES no son sino la reunión de todos
estos conjuntos Zi).
Resta mostrar que L(G)=L(G’).
Recordemos que P’ es P-{producciones eliminadas por incluir No Terminales inaccesibles},
es decir, P’P, luego es claro que si wL(G’), es decir, S=>*w con producciones de P’, lo
mismo puede hacerse en G con las mismas producciones, es decir, wL(G).
Si wL(G) entonces wL(G’): Supongamos que no, que una cadena en L(G) no está en
L(G’). Es decir, S=>*w con producciones de P donde se ha utilizado una producción -que
incluye un No Terminal, digamos X- de G que no está en G’, pero entonces por un lado xN’,
es decir, es imposible que S=>*yXz, por otro lado como la derivación S=>*w que incluye a X
no significa otra cosa que S deriva una cadena que incluye a X (que luego deriva en w), es
decir, XN’(=ACCESIBLES), esta contradicción prueba el enunciado.
Ejemplo:
Sea la GLC G=({S,B,C},{a,b},P,S)
P:
S-->aBa
B-->a
C-->ab
Z0={S}
Z1={S} {a,B}={S,a,B}
Z2={S,a,B} {a,B}={S,a,B}
Como Z1=Z2 entonces ACCESIBLES={S,B}, INACCESIBLES={C}, T’={a}.
P’:
S-->aBa
B-->a
215
Dada una GLC G tal que L(G), para construir una GLC G’ limpia tal que L(G)=L(G’),
eliminamos –en orden- las producciones renombradoras, los No Terminales inútiles y los No
Terminales inaccesibles. El orden es relevante.
Ejemplo:
Con la GLC G=({S,X,A,B},{a},P,S)
P:
S-->X
X-->AB
S-->aa
X-->a
A-->a
Si eliminamos primero los No Terminales inaccesibles (ninguno, todos son accesibles), luego
las producciones renombradoras obteniendo {S-->AB,S-->a,X-->AB,S-->aa,X-->a,A-->a} y
finalmente los No Terminales inútiles –{B}- queda el siguiente conjunto de producciones
{ S-->a,S-->aa,X-->a,A-->a } que evidentemente no es de una GLC limpia pues X y A son
inaccesibles.
216
Caso base: X=>*w en un paso de derivación, es decir, X=>w con X-->wP1, esta producción
está en P1 sólo porque X-->wP, por la última parte de la construcción de P1, recordemos que
XN, entonces X=>*w con producciones de P.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que X=>*w en k pasos de derivación que pueden desglosarse así:
X=>Z1..Zi..Zm con m2, pues las producciones de P1 que no tienen un Terminal en
*
=> w1...wm=w su parte derecha , tienen ||2.
Además Zi=>*wi, es claro que wiT*: Por un lado si ZiN, dado que esta derivación toma
menos de k pasos, resulta que, por hipótesis inductiva, la misma puede hacerse con
producciones de P. Por otro lado, si ZiN, entonces Zi=Xaj, y la derivación Xaj=>*wi debe
hacerse en un paso con wi=aj, pues por la forma de construcción de P1 sólo la producción
Xaj-->aj tiene a Xaj como parte izquierda; además el primer paso de derivación X=>Z1..Zi..Zm
se da porque X-->Z1..Zi..ZmP1, o lo que es lo mismo X-->Z1..Xaj..ZmP1, entonces por la
forma de construcción de P1, la producción X-->Z1..wi..ZmP, recuerde que wi=aj y nótese que
hemos simplificado el razonamiento a un sólo Zi, si más de un ZiN, el razonamiento es
semejante, luego como cada uno de los otros Zj=>*wj con producciones de P, resulta que
X=>Z1..wi..Zm=>*w con producciones de P.
Resta mostrar que si wL(G) entonces wL(G1), también probaremos por inducción sobre el
número de pasos de derivación el enunciado más general siguiente:
Si X=>*w -wT*- con producciones de P entonces X=>*w con producciones de P1.
Caso base: X=>*w en un paso de derivación, es decir, X=>w con X-->wP. Sea w=ej1...ejm,
si m=1 entonces –por la forma de construir P1- X-->wP1, luego X=>*w con producciones de
P1; si m>1, entonces –por la forma de construir P1- las siguientes producciones están en P1:
(X-->ej1...ejm)[a1/Xa1,...,am/Xam] junto a {Xai-->ai / aiT}, es decir,
X-->Xj1...Xjm junto a {Xai-->ai / aiT}, de donde se desprende que Xji-->eji está en P1, es decir,
Xji=>eji. Luego, con producciones de P1 es posible X=>Xj1...Xjm=>*ej1...ejm.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que X=>*w en k pasos de derivación que pueden desglosarse así:
X=>ej1...ejm con m2, pues P no tiene producciones renombradoras
=>*w1...wm=w
Donde eji=>*wi -es claro que wiT*- en menos de k pasos, es decir, por hipótesis inductiva,
eji=>*wi puede hacerse con producciones de P1.
El primer paso ha debido utilizar la producción X-->ej1...ejmP, entonces –por la forma de
construir P1- las siguientes producciones están en P1:
(X-->ej1...ejm)[a1/Xa1,...,am/Xam] junto a {Xai-->ai / aiT}, es decir,
X-->Xj1...Xjm junto a {Xai-->ai / aiT}, de donde se desprende que Xji-->eji está en P1, es decir,
Xji=>eji. Luego, con producciones de P1 es posible X=>Xj1...Xjm=>*ej1...ejm=>*w1...wm. Es
decir, wL(G1).
Sea la GLC G1=(N1,T,P1,S) como se indica arriba, construimos así la GLC G’=(N’,T,P’,S).
217
P’:
Y --> X1Zj1
Zj1 --> X2Zj2 si Y-->X1...XmP1 con m3
... los ZjiN1, son nuevos No Terminales
Zj(m-2) --> Xm-1Xm
A --> Si A-->P1 con |2
N’ = N1 { Zji / Zji es un nuevo No Terminal añadido en la construcción de P’}
L(G1)=L(G’).
En efecto, mostraremos que si wL(G1) entonces wL(G’), es decir, si S=>*w con
producciones de P1 entonces S=>*w con producciones de P’.
Sea yAz=>yz un paso de derivación cualquiera (de S=>*w) dado con la producción A--> de
P1, la misma puede simularse en P’: si A-->P1 es tal que |2, por construcción de P’, esta
producción está -precisamente- en P’; por otro lado A-->P1 es tal que |2, entonces debe
ser del tipo A-->X1...Xm, otra vez por construcción de P’, las siguientes producciones están en
P’: A-->X1Zj1, Zj1-->X2Zj2,..., Zj(m-2)-->Xm-1Xm, luego en P’ es posible la siguiente derivación
yAz=>yX1Zj1z=>yX1X2Zj2z=>...=>yX1...Xm-2Zj(m-2)z=>yX1...Xmz, es decir, yAz=>*yz con
producciones de P’. Luego, cada paso en S=>*w con producciones de P1 puede simularse con
producciones de P’, es decir, S=>*w con producciones de P’.
Inversamente:
Si wL(G’) entonces wL(G1)
Demostración:
Por inducción sobre el número de pasos de derivación probaremos el enunciado más general
siguiente:
Si Y=>*w -YN1, wT*- con producciones de P’ entonces Y=>*w con producciones de P1.
Caso base: Y=>*w en un paso de derivación, es decir, Y=>w con Y-->wP’, por la forma de
las producciones de P’ w=a. Observando la construcción de P’, esta producción está presente
porque Y-->wP1, luego Y=>*w con producciones de P1.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que Y=>*w en k pasos de derivación, con producciones de P’.
Desglosaremos esta derivación en sus formas genéricas posibles así:
a) Si el primer paso de derivación es así Y=>X1X2 con X1,X2N1, donde se ha utilizado la
producción Y-->X1X2P’, por la forma de construir P’ debe suceder que Y-->X1X2P1.
Luego la derivación es Y=>X1X2=>*w1w2 con w=w1w2, X1=>*w1 y X2=>*w2, estas dos
últimas derivaciones se hacen en menos de k pasos, así -por hipótesis de inducción- pueden
hacerse con producciones de P1, es decir, Y=>*w con producciones de P1.
b) Si el primer paso de derivación es así Y=>X1X2, por la la forma de construir P’ no es
posible que X1N1, es decir, X1N1.
218
c) Si el primer paso de derivación es así Y=>X1Zj1 con X1N1 y Zj1N1 (es un nuevo No
Terminal), donde se ha utilizado la producción Y-->X1Zj1 de P’, entonces por la forma de
construir P’, también deben estar presentes las producciones Zj1-->X2Zj2,...,Zj(m-2)-->Xm-1Xm,
de manera que la derivación es Y=>X1Zj1=>X1X2Zj2=>...=>X1...Xm=>*w1...wm donde
w=w1...wm, X1=>*w1, ... , Xm=>*wm, cada XjN1, estas derivaciones se hacen en menos de k
pasos, luego -por hipótesis de inducción- cada derivación Xj=>*wj puede hacerse con
producciones de P1. Además, las producciones mencionadas están en P’ porque
Y-->X1...XmP1, es decir, es posible derivar Y=>X1...Xm =>*w con producciones de P1.
Ejemplo:
Sea la GLC G=({S,X,Y},{a,b,c},P,S)
P:
S --> Sabcc
S --> XX
X --> XYa
Y --> XSSX
X --> abb
Y --> a
219
De X --> XaXbXb vienen X --> XaZ7
Z7 --> XbXb
Las restantes producciones S --> XX
se copian tal cual Y --> a
pues tienen |2 Xa --> a
Xb --> b
Xc --> c
N’={S,X,Y,Xa,Xb,Xc,Z1,Z2,Z3,Z4,Z5,Z6,Z7}
Que evidentemente ya está en FNCH y que genera el mismo lenguaje que G.
220
En rigor para este resultado, no es necesario que G sea una GLC limpia, es suficiente que
además de las producciones X -->X,...,X-->Xk que hacen que X sea recursivo por
izquierda de primer orden, existan las producciones X -->,...,X--> m ( i no tiene a X como
cabeza).
Ejemplo:
Sea la GLC G=({S,X,B},{a,b},P,S)
P:
S-->aX 1=aX
S-->SaSaX 1=aSaX
X-->Xa
X-->XXX
X-->aBa
X-->ab
B-->aXB
B-->b
Es evidente que tanto X como S son No Terminales recursivos por izquierda de primer orden.
Trabajaremos primero con S, ya hemos anotado arriba los i y losj. Todo el conjunto de
producciones resultantes se anota a continuación, donde además se destacan los i y losj
para el No Terminal X, obviamente Z1 es un Nuevo No Terminal.
S-->aX
Z1-->aSaXZ1
Z1-->aSaX
S-->aXZ1
X-->Xa 1=a
X-->XXX 2=XX
X-->aBa 1=aBa
X-->ab 2=ab
B-->aXB
B-->b
Trabajando ahora con X, finalmente la GLC G’=(N’,{a,b},P’,S) es como sigue, Z2 es nuevo.
P’:
S-->aX X-->aBaZ2
Z1-->aSaX X-->abZ2
Z1-->aSaXZ1 X-->aBa
S-->aXZ1 X-->ab
Z2-->aZ2 B-->aXB
Z2-->XXZ2 B-->b
Z2-->a
Z2-->XX
N’={S,X,B,Z1,Z2}
221
Construcción de una GLC en FNG a partir de otra GLC arbitraria
Previamente necesitamos el siguiente resultado imprescindible.
Sea G=(N,T,P,S) una GLC, sean X,YN con XY, sea X-->YP con ,(NT) *, y sea
{Y-->,...,Y--> m}P el conjunto de todas las producciones de P con parte izquierda Y
entonces la GLC G’=(N,T,P’,S) donde P’= (P – {X-->Y}) {X-->,...,X--> m} es
tal que L(G)=L(G’).
Demostración:
Mostraremos que cualquier derivación en P’ que involucre el uso de alguna producción
X-->j puede hacerse en P (obviamente las derivaciones que no involucren esta producción
pueden hacerse idénticamente en P y en P’). Analicemos sólo la parte concerniente a esta
producción: seguramente tendremos una (sub)derivación del tipo X=>j, pero la
producción X--> jP’ porque Y,Y-->jP, es decir, en P puede hacerse la derivación
X=>Y=> j.
Inversamente, mostraremos que cualquier derivación en P que involucre el uso de la
producción X-->Y puede hacerse o simularse en P’ (obviamente las derivaciones que no
involucren esta producción pueden hacerse idénticamente en P y en P’). Analicemos sólo la
parte concerniente a esta producción: seguramente tendremos una (sub)derivación del tipo
X=>Y, el No Terminal Y debe dar paso –en la derivación- a una otra subcadena, para ello
en P hemos de utilizar alguna producción Y-->j, un caso -genérico- posible es que la
(sub)derivación sea X=>Y=>j, pero ambos pasos de derivación pueden simularse en P’
así X=>j utilizando la producción X--> j que está presente en la construcción de este
conjunto de producciones (el caso mencionado es genérico en el sentido que si Y se reemplaza
en un paso de derivación posterior al paso X=>Yello no afecta nuestro razonamiento más
que en la descripción de la derivación pues finalmente Y se convertirá en j).
Al construir P’ a partir de P, es posible que algún(os) No Terminal(es) se haga(n) recursivo(s)
por izquierda de primer orden.
Ejemplo:
Sea la GLC Trabajaremos con la producción S-->YaZ, obviamente S
G=({S,X,B},{a,b},P,S) juega el papel de X en el enunciado, = y =aZ.
P: {Y-->aZY,Y-->SaS,Y-->b} tienen parte izquierda Y.
S-->YaZ Construimos así la GLC G’=({S,X,B},{a,b},P’,S)
Z-->aSa P’:
Z-->a S-->aZYaZ
Y-->aZY S-->SaSaZ
Y-->SaS S-->baZ
Y-->b Z-->aSa
Z-->a
Y-->aZY
Y-->SaS
Y-->b
222
Cuando este resultado previo se utilice con producciones X-->Y, que como en el ejemplo
tienen =, es decir, con producciones X-->Y, nos referiremos al hecho de reemplazar
X-->Y por X--> ,...,X--> m -donde{Y-->,...,Y--> m} es el conjunto de todas las
producciones de P con parte izquierda Y- bajo el nombre de reemplazar la cabeza Y (en la
producción X-->Y por la parte derecha de todas las producciones donde Y es parte
izquierda).
Cuando vimos la FNCH hicimos que todas las partes derechas –excepto las que son de un sólo
Terminal- sean cadenas de No Terminales, de manera muy semejante si a partir de una GLC
con producciones P, construimos otra GLC G1 con producciones
Demostración:
Establecimiento de un orden en N cambiando de nombre a los No Terminales:
Sin pérdida de generalidad podemos cambiar de nombre a los No Terminales por V1,V2, etc.,
estableceremos un orden a partir de los subíndices, así V1<V2<V3 etc.
Ejemplo:
Si N={S,A,B,C}.
Lo cambiamos por N={V1,V2,V3,V4}.
Hay que cambiar también los nombres de los No Terminales en el conjunto de producciones.
Se supone que tenemos |N|=n (es decir, n No Terminales)
223
Paso 1 de 5:
Establecer un orden en N, cambiando de nombre a los No Terminales en caso de ser
necesario. Tomaremos a P como conjunto de trabajo, todas las condiciones sobre
producciones en lo que sigue se refieren a producciones de P.
Paso 2 de 5:
Para k := 1,..., n
Para j:= 1,..., k-1
Si hay una producción Vk-->Vjfíjese que la condición es que k>j
Entonces Reemplazar la cabeza Vj
FinPara_j
Si aparece o existe recursividad por izquierda de primer orden para Vk
Entonces eliminarla
FinPara_k
Paso 3 de 5:
Para i := n-1,..., 1
Si hay una producción Vi-->Vjcon i<j
Entonces Reemplazar la cabeza Vj
FinPara_i
Para k := 1,..., n
Si hay una producción Zj-->Vk (Zj es un nuevo No Terminal)
Entonces Reemplazar la cabeza Vk
FinPara_k
Paso 4 de 5:
Mayusculizar P
Paso 5 de 5:
Si es necesario re-nombrar los No Terminales (excepto los nuevos) a como estaban antes.
Aunque esta última GLC ya está en FNG es posible que algunos No Terminales sean
inaccesibles, no es necesario pero es recomendable hacer una nuevo proceso de limpieza.
224
Dado que los cambios que se hacen en el conjunto de producciones de trabajo resultan de la
eliminación de la recursividad por izquierda de un No Terminal o del reemplazo de una
producción por otras, es claro que -según los resultados previos- L(G)=L(G’).
Ejemplo:
Sea la GLC G2=({S,A,B,X},{a,b},P2,S)
P2:
S-->A
A-->BaX
B-->aXB B-->AaA B-->b
X-->aAa X-->a
225
Es claro que surgió recursividad por izquierda para V3, la eliminamos:
Sabiendo que están las
Se reemplaza por estas:
producciones:
V3-->aV4V3Z
V3-->aV4V3
V3-->bZ
V3-->b
Z-->aV4aV2Z
La producción:
Z-->aV4aV2
V3-->V3aV4aV2
De donde todo el conjunto de producciones es ahora así, Z es un nuevo No Terminal:
V1-->V3aV4
V2-->V3aV4
V4-->a
V4-->aV2a
V3-->aV4V3
V3-->b
V3-->aV4V3Z
V3-->bZ
Z-->aV4aV2Z
Z-->aV4aV2
Terminamos los ciclos del paso 2 y para k=4 no hay problema.
Paso 3:
Primer ciclo (fíjese que va de mayor a menor, en nuestro caso de 3 a 1): Para i=3 no hay
problema; para i=2 si.
En V2-->V3aV4 es evidente que i<j (2<3), reemplazamos la cabeza V3 así:
Con este reemplazo el nuevo grupo de
todas las producciones es:
V1-->V3aV4
V2-->V3aV4 V4-->a
V4-->aV2a
se reemplaza por V3-->aV4V3
V3-->b
V2-->aV4V3aV4 V3-->aV4V3Z
V2-->baV4 V3-->bZ
V2-->aV4V3ZaV4 Z-->aV4aV2Z
V2-->bZaV4 Z-->aV4aV2
V2-->aV4V3aV4
V2-->baV4
V2-->aV4V3ZaV4
V2-->bZaV4
Siempre en el primer ciclo del paso 3, también hay problemas con i=1.
En V1-->V3aV4 es evidente que i<j (1< 3), reemplazamos la cabeza V3 así:
226
Con este reemplazo el nuevo grupo de
todas las producciones es:
V1-->aV4V3aV4
V1-->baV4
V1-->aV4V3ZaV4
V1-->V3aV4 V1-->bZaV4
V4-->a
se reemplaza por V4-->aV2a
V3-->aV4V3
V1-->aV4V3aV4 V3-->b
V1-->baV4 V3-->aV4V3Z
V1-->aV4V3ZaV4 V3-->bZ
V1-->bZaV4 Z-->aV4aV2Z
Z-->aV4aV2
V2-->aV4V3aV4
V2-->baV4
V2-->aV4V3ZaV4
V2-->bZaV4
Segundo Ciclo: no hay problema.
Paso 4: Mayusculizando las producciones el resultado es como sigue (con Xa en vez de ‘a’).
V1-->aV4V3XaV4
V1-->bXaV4
V1-->aV4V3ZXaV4
V1-->bZXaV4
V4-->a
V4-->aV2Xa
V3-->aV4V3
V3-->b
V3-->aV4V3Z
V3-->bZ
Z-->aV4XaV2Z
Z-->aV4XaV2
V2-->aV4V3XaV4
V2-->bXaV4
V2-->aV4V3ZXaV4
V2-->bZXaV4
Xa-->a
227
P’:
S-->aXBXaX
S-->bXaX
S-->aXBZXaX
S-->bZXaX
X-->a
X-->aAXa
B-->aXB
B-->b
B-->aXBZ
B-->bZ
Z-->aXXaAZ
Z-->aXXaA
A-->aXBXaX
A-->bXaX
A-->aXBZXaX
A-->bZXaX
Xa-->a
N’={S,A,B,X,Z,Xa}
Que ya está en FNG y es además una GLC limpia.
Demostración:
1) A partir de G construimos otra GLC G1=(N1,T,P1,S) en FNG misma que tendrá todas sus
producciones del tipo A-->a, donde AN1, a, N1*
228
A-->a que hemos copiados con AN1, ó
A-->aB que hemos copiado con A,BN1, ó
A-->aZk que resultan del proceso de partición con AN1, Zk un nuevo No Terminal, ó
Zj-->XiZk que resultan del proceso de partición con XiN1 y Zj,Zk nuevos No Terminales
Fíjese que para todos los No Terminales en N1: si son parte izquierda de una producción,
entonces la parte derecha de dicha producción empieza con un Terminal.
Finalmente para construir la GLC G’=(N’,T,P’,S) a partir de G2, no hacemos más que
reemplazar la cabeza Xi (en la producción Zj-->XiZkP2 –donde XiN1- por la parte derecha
de todas las producciones donde Xi es parte izquierda).
Es evidente que en este reemplazo, la subcadena que se reemplace -en vez de la cabeza Xi-
será del tipo a, ó aB ó aZk que darán lugar a la GLC en 2FNG que estamos buscando.
Ya demostramos que al reemplazar la cabeza W el lenguaje resultante de la nueva gramática
es l-equivalente a la gramática original, es decir, L(G2)=L(G’).
Ejemplo:
Partiremos de una GLC limpia y en FNG, nos resta dar el segundo paso del procedimiento.
Sea la GLC G1=({S,B,X,Y},{a,b},P1,S) en FNG
P1:
S-->aBBXX Y-->aB
X-->aSB B-->aXB
B-->bSYS
B-->b
X-->a
Construimos así la GLC G2=(N2,{a,b},P2,S)
P2:
De S-->aBBXX vienen S-->aZ1
Z1-->BZ2
Z2-->BZ3
Z3-->XX
Y-->aB se copia Y-->aB
De X-->aSB vienen X-->aZ4
Z4-->SB
De B-->aXB vienen B-->aZ5
Z5-->XB
De B-->bSYS vienen B-->bZ6
Z6-->SZ7
Z7-->YS
B-->b se copia B-->b
X-->a se copia X-->a
N2={S,B,X,Y,Z1,Z2,Z3,Z4,Z5,Z6,Z7}
229
P’:
S-->aZ1 Z1-->aZ5Z2
Y-->aB Z1-->bZ6Z2
B-->aZ5 Z1-->bZ2
B-->bZ6 Z2-->aZ5Z3
B-->b Z2-->bZ6Z3
X-->aZ4 Z2-->bZ3
X-->a Z3-->aZ4X
Z3-->aX
Z4-->aZ1B
Z5-->aZ4B
Z5-->aB
Z6-->aZ1Z7
Z7-->aBS
Que está en 2FNG.
’:
1) ’(q0’,,Z’) = {(q0,ZZ’)}
2) ’(qi,c,X) = (qi,c,X) qiK, c( {}), X
3) ’(qj,,X) = {(qe,X)} qjF, X{Z’}
4) ’(qe,,X) = {(qe,)} X{Z’}
Nótese que el inciso 2 nos dice que copiemos .
T(A)=T(A’). En efecto, mostraremos inicialmente que si wT(A) entonces wT(A’), es
decir, si q0,w,|--*(qj,,) en A con las reglas (qjF) entonces q0’,w,Z’|--*(qe,,) en A’.
Veamos qué sucede en A’ con la cadena w:
q0’,w,Z’|-- q0,w,ZZ’) por 1
|--*(qj,,Z’) por hipótesis y por 2, qjF
|-- (qe,,Z’) por 3
|--*(qe,,) por 4
Es decir, q0’,w,Z’|--*(qe,,) en A’.
Inversamente, si q0’,w,Z’|--*(qe,,) en A’ entonces q0,w,|--*(qj,,) en A (qjF).
Analicemos cuándo sucede que q0’,w,Z’|--*(qe,,) en A’:
230
A partir deq0’,w,Z’) el único movimiento que se puede dar en A’ es utilizando la regla 1
pues ninguna otra regla tiene a q0’ como estado de partida : q0’,w,Z’|-- q0,w,ZZ’), a partir de
aquí, por la forma de construir ’, la única forma de consumir toda la cadena w es
consumiéndola con las reglas de 2 (pues las reglas 3 y 4 no consumen símbolos de entrada), la
única forma de llegar al estado qe es partiendo de un estado que era final en F -sin importar el
contenido de la pila- lo que sólo hacen las reglas de 3, y la única forma de vaciar la pila es,
estando en qe, con las reglas 4. Si juntamos estos datos resulta que estando en q0,w,ZZ’) para
llegar a (qe,,), debe ocurrir que: q0,w,ZZ’)|--*(qj,,Z’) con la reglas de 2 y qjF. Luego
(qj,,Z’)|--* (qe,,) con las reglas de 3 y 4.
Pero entonces, como q0,w,ZZ’)|--*(qj,, Z’) con la reglas de 2 y qjF, y como Z’, es
decir, ninguna regla de 2 incluye a Z’, debe ser posible que q0,w,Z)|--*(qj,,) con la reglas de
2 y qjF, pero las reglas de 2 no son otras que las reglas de , es decir, q0,w,Z|--*(qj,,) en
A.
Ejemplo:
Sea el APe.f. A=({q0,q1},{a,b},,,q0,Z,F)
={Z}
F={q1}
:
(q0,a,Z)={(q0,Z),(q1,Z)}
(q1,b,Z)={(q0,Z),(q1,Z)}
Demostración:
La idea es simular una pila “vacía” utilizando un nuevo símbolo inicial de la pila llamado Z’.
Cuando estemos en tal situación, es decir cuando tengamos una pila vacía simulada (la pila no
está realmente vacía) transitamos hacia el estado final qf.
Sea A=(K,,,,q0,Z,{}) el AP –Z’; q0’,qfK-, construimos así el APe.f.
A’=(K{q0’,qf}, , Z’}, ’, q0’, Z’, {qf})
231
’:
1) ’(q0’,,Z’) = {(q0,ZZ’)}
2) ’(qi,c,X) = (qi,c,X) qiK, c( {}), X
3) ’(qi,,Z’) = {(qf,Z’)} qiK
Nótese que el inciso 2 nos dice que copiemos .
T(A)=T(A’).
En efecto: Si wT(A) Entonces wT(A’), es decir,
Si q0,w,|--*(qi,,) en A entonces q0’,w,Z’|--*(qf,,Z’) en A’.
Demostración:
Veamos qué sucede en A’ con la cadena w:
q0’,w,Z’|-- q0,w,ZZ’) por 1
*
|-- (qi,,Z’) por hipótesis y por 2
|-- (qf,,Z’) por 3
Es decir, q0’,w,Z’|--*(qf,,Z’) en A’.
Inversamente:
Si q0’,w,Z’|--*(qf,,Z’) en A’ entonces q0,w,|-- *(qi,,) en A.
Demostración:
Analicemos cuándo sucede que q0’,w,Z’|--*(qf,,Z’) en A’:
A partir deq0’,w,Z’) el único movimiento que se puede dar en A’ es utilizando la regla 1
pues ninguna otra regla tiene a q0’ como estado de partida : q0’,w,Z’|-- q0,w,ZZ’), a partir de
aquí, por la forma de construir ’, la única forma de consumir toda la cadena w es
consumiéndola con las reglas de 2 (pues las reglas de 3 no consumen símbolos de entrada), y
la única forma de llegar al estado qf es partiendo de un estado en K con el contenido de la pila
siendo Z’, lo que sólo hace 3.
Si juntamos estos datos resulta que estando en q0,w,ZZ’) para llegar a (qf,,Z’), debe ocurrir
que: q0,w,ZZ’)|--*(qi,,Z’) con la reglas de 2. Luego (qi,,Z’)|--* (qf,,Z’) con 3. Pero
entonces, como q0,w,ZZ’)|--*(qi,,Z’) con la reglas de 2 y como Z’, es decir, ninguna regla
de 2 incluye a Z’, debe ser posible que q0,w,Z)|--*(qi,,) con la reglas de 2, pero las reglas de
2 no son otras que las reglas de , es decir, q0,w,Z|--*(qi,,) en A.
Ejemplo:
Sea el AP A=({q0,q1,qe},{a,b},{Z},,q0,Z,{})
(q0,a,Z)= {(q0,Z),(q1,Z)}
(q1,b,Z)= {(q0,Z),(q1,Z)}
(q1,,Z)= {(qe,)}
(qe,,Z)= {(qe,)}
232
Construimos así el APe.f. A’=({q0,q1,q0’, qe , qf },{a,b},{Z,Z’},’,q0’,Z’,{qf})
’(q0’,,Z’) = {(q0,ZZ’)}
’(q0,a,Z)= {(q0,Z),(q1,Z)}
’(q1,b,Z)= {(q0,Z),(q1,Z)}
’(q1,,Z)= {(qe,)}
’(qe,,Z)= {(qe,)}
’(q0,,Z’) = {(qf,Z’)}
’(q1,,Z’) = {(qf,Z’)}
’(qe,,Z’) = {(qf,Z’)}
Demostración:
Sea G=(N,T,P,S) una GLC en FNG, construimos así el AP A=({q0},,N,,q0,S,{}).
Nótese que el símbolo inicial de la pila es S y no Z y que tenemos un único estado q0.
: (q0,) (q0,a,X) si X-->a P
L(G)=T(A).
En efecto, primero mostraremos que
Si S=>*w Entonces q0,w,S|--*(q0,,)
Por inducción sobre el número de pasos de derivación.
Caso base: S=>*w en un paso, es decir, S=>w lo que sólo puede hacerse si S-->wP,
pero entonces por construcción de A (q0,)(q0,w,S), luego en A es posible el siguiente
movimiento q0,w,S|--(q0,,), es decir, q0,w,S|--*(q0,,).
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Supongamos que S=>*w es una derivación más a la izquierda que toma k
pasos. Desglosemos esta derivación más a la izquierda así: S=>*uX=>ua donde w=ua,
= y X-->aP. Es claro que S=>*u’ -con ’=X- en menos de k pasos, luego por
hipótesis inductiva q0,u,S|--*(q0,,’), es decir, q0,w,S|--*(q0,a,X). Además, por
construcción de A, como X-->aP, tenemos que (q0,)(q0,a,X), luego es posible dar el
siguiente movimiento (q0,a,X)|--*(q0,,), es decir, en A es posible q0,w,S|--*(q0,,) pues
=.
233
Paso inductivo: Supongamos que q0,w,S|--*(q0,,) en k movimientos. Desglosemos estos
movimientos en su último movimiento y el resto, para ello es bueno recordar que por la forma
de construir , las reglas de transición sólo permiten movimientos tipo 1, es decir el último
movimiento de nuestro desglose debe consumir un símbolo y debe preguntar por un tope de
pila que puede tener o no símbolos debajo de él, de manera que podemos suponer que w=ua,
= en este desglose: q0,ua,S|--*q0,a,X|--(q0,,), donde los primeros movimientos
toman menos de k pasos y pueden dar lugar legítimamente a lo siguiente q0,u,S|--*q0,,X;
pero entonces por hipótesis inductiva S=>*uX. El último movimiento q0,a,X|--(q0,,)
ha debido utilizar una regla donde (q0,)(q0,a,X), que está en A sólo porque X-->aP.
Luego, en G es posible S=>*uX=>ua, es decir, S=>*w pues = y w=ua.
Por los anteriores resultados tenemos que S=>*w si y sólo si q0,w,S|--*(q0,,), haciendo
= resulta que S=>*w si y sólo si q0,w,S|--*(q0,,), es decir, L(G)=T(A).
Ejemplo:
Sea la GLC en FNG G=({S,B},{a,b},{S-->aSB,S-->aB,B-->b},S)
Construimos así el AP A=({q0},{a,b},{S,B},,q0,S,{})
:
(q0,a,S)={(q0,SB),(q0,B)}
(q0,b,B)= {(q0,)}
Hay otra forma de construir el APA que no requiere nada de G (ni forma normal ni higiene).
Sea G=(N,T,P,S) una GLC.
En P: aT reemplazamos a por Xa. Llamaremos T’ a todos estos nuevos símbolos.
Sea P’ el conjunto de producciones así reemplazadas.
Construimos así el APA=({q0},,(NT’),,q0,S,{})
:
1) (q0,) (q0,,X) si X--> P’
2) (q0,Xa,a) = {(q0,)} aT
Ejemplo:
Sea la GLC G=({S,B},{a,b},{S-->aSb, S-->ab},S)
Construimos así el AP A=({q0},{a,b},{S,B,Xa,Xb},,q0,S,{})
:
(q0,,S)={(q0,XaSXb),(q0,XaXb)}
(q0,Xa,a) = {(q0,)}
(q0,Xb,b) = {(q0,)}
234
Denominaremos cuasi-gramática libre de contexto (cuasi-GLC) a una cuádrupla G=(N,T,P,S)
cuyo comportamiento es semejante a las GLC’s y cuyo conjunto de producciones siguen la
definición de las producciones de una GLC excepto por la presencia de producciones
borradoras.
Ejemplo:
G=({S},{a},{S-->aSa, S-->},S) es una cuasi-GLC.
Sea G una cuasi-GLC entonces es posible construir un GLC G’ tal que L(G’)=L(G)-{}.
Demostración:
Hacemos notar previamente que una cuasi-GLC no necesariamente genera la cadena vacía,
por ejemplo la cuasi-GLC G=({S,B},{a},{S-->aB,B-->},S) es tal que L(G)={a}.
Sea G=(N,T,P,S) una cuasi-GLC.
Sea ANULABLES = { AN / A=>* }
Identificaremos los No Terminales ANULABLES así:
B0 = {A / A--> P}
Bi+1 = Bi {A / A-->Bi+}
Si Bi=Bi+1 entonces Bi=ANULABLES
Construimos así la GLC G’=(N,T,P’,S).
P’ = { A--> / A-->P, } (*)
{ A-->e1e2...em / A-->0e11e2...em mP,
m , | 0e11e2...em m| 2
ei(NT), jANULABLES*} (**)
Es decir:
(*) Copiamos todas las producciones de P que no sean borradoras; y
(**) Añadimos las producciones que resulten de hacer lo siguiente:
En todas y cada una de las producciones de las producciones de (*) cuya parte derecha
tenga por lo menos dos símbolos, reemplazar uno o más símbolos ANULABLES de la
parte derecha por es decir, borrar las subcadenas que estén en ANULABLES*).
Excepto si resultare una producción borradora (que por supuesto no se añade).
Mostramos que si A=>* entonces AANULABLES por inducción sobre el número de pasos
de derivación (es obvio que si A está en algún Bi está en ANULABLES).
Caso base: A=> en un paso, es decir, A-->P, luego A está en B0, es decir,
AANULABLES.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que A=>* en k pasos de derivación. Podemos desglosar esta derivación
en su primer paso y los restantes así: A=>ej1...ejm=>* donde A-->ej1...ejmP, eji=>*.
235
Es claro que cada eji es un No Terminal pues los Terminales no pueden derivar ; como
eji=>* toma menos de k pasos, por hipótesis inductiva ejiANULABLES, pero entonces
ej1,...,ejm están en algún Bh, luego la cadena ej1...ejmBh+ y por tanto A está en Bh+1, es decir,
AANULABLES.
El hecho de que si AANULABLES entonces A=>* sigue de la forma indicada de construir
este conjunto (aunque puede pensarse una inducción sobre i para Bi pues ANULABLES no es
más que la reunión de todos estos conjuntos Bi).
Demostración:
Caso base: A=>w en un paso de derivación en G con A-->wP (w), es claro por (*) que
esta producción está en P’, luego A=>*w en G’.
Hipótesis inductiva: El enunciado es cierto para derivaciones de menos de k pasos.
Paso inductivo: Sea que A=>*w en k pasos de derivación con producciones de P (w).
Desglosaremos esta derivación en su primer paso y los restantes así:
A=>w0X1w1X2w2...Xmwm=>*w0v1w1v2w2...vmwm así pues w=w0v1w1v2w2...vmwm, donde en el
primer paso se ha utilizado A-->w0X1w1X2w2...XmwmP con m XiN, wjT* y donde
Xj=>*vj en menos de k pasos con producciones de P. Si vj por hipótesis inductiva Xj=>*vj
con producciones de P’, en cambio si vj= es claro que XjANULABLES.
Sea Yj=Xj si vj, Yj= en otro caso: por (**) es claro que A-->w0Y1w1Y2w2...Ymwm está en
P’. Luego, A=>w0Y1w1Y2w2...Ymwm=>*w0v1w1v2w2...vmwm puede hacerse en G’.
Demostración:
Cuando la derivación A=>*w en G’ utiliza sólo producciones que estaban en P, es obvio que
puede hacerse en G. Supongamos que un paso cualquiera de la derivación A=>*w en G’ se
hace utilizando una producción (nueva) de P’ que no estaba en P: sea A=>e1e2...em
dicho paso de derivación efectuado con la producción A-->e1e2...emP’, por la forma de
construir P’ dicha producción está presente porque A-->0e11e2...em mP con
jANULABLES*, es decir, j=>*. Pero entonces en G es posible la derivación
A=>0e11e2...em m=>*e1e2...em, es decir,A=>*e1e2...em, luego el paso de
derivación A=>e1e2...em con una producción de P’ puede simularse en P.
Ejemplo:
Sea la cuasi-GLC G=({S,A,B,F},{a,b},P,S)
236
P:
S -->aSb
S -->BaA
S -->abF
S-->ABA
S-->A
F-->ASA
A-->
B-->
237
P:
1) [qi,X,qkm]-->c[qj,Y1,qk1][qk1,Y2,qk2][qk2,Y3,qk3]...[qk(m-2),Ym-1,qk(m-1)][qk(m-1),Ym,qkm]
c {}), Yj, qkiK si (qj,Y1Y2...Ym)(qi,c,X)
2) [qi,X,qj]-->c c {}) si (qj,)(qi,c,X)
3) S-->[q0,Z,qi] qiK
En 1, fíjese muy atentamente las coincidencias de los qki. Por ejemplo el qkm de la parte
izquierda es el mismo que el qkm de la última terna de la parte derecha.
L(G)=T(A).
238
Y donde qh,w1,Y1)|--*(qk1,,), qk(m-1),wm,Ym|--*(qj,,) y qk(n-1),wn,Yn|--*(qkn,,) para
n=2,...,m-1 en menos de k movimientos. Por hipótesis inductiva [qh,Y1,qk1]=>*w1,
[qk(m-1),Ym,qj]=>*wm y [qk(n-1),Yn,qkn]=>*wn para n=2,...,m-1 son posibles en P. Luego en G es
posible la derivación
[qi,X,qj]=>c[qh,Y1,qk1][qk1,Y2,qk2][qk2,Y3,qk3]...[qk(m-2),Ym-1,qk(m-1)][qk(m-1),Ym,qj]
=>*cw1[qk1,Y2,qk2][qk2,Y3,qk3]...[qk(m-2),Ym-1,qk(m-1)][qk(m-1),Ym,qj]
=>*cw1...wm-1[qk(m-1),Ym,qj]
=>*cw1...wm-1wm
Es decir, [qi,X,qj]=>*w pues w=cw1...wm.
Con X=Z y qi=q0 los resultados anteriores dicen que q0,w,Z|--*(qj,,) si y sólo si
[q0,Z,qj]=>*w, además S=>*[q0,Z,qj] por 3), luego q0,w,Z|--*(qj,,) si y sólo si S=>*w, es
decir, L(G)=T(A).
Ejemplo:
Sea el siguiente APA=(K,,,,q0,Z,{})
K{q0,q1{a,b ={Z,B}
(q0,a,Z)= {(q0,ZB)}
(q0,,Z) = {(q1,)}
(q1,b,B)= {(q1,)}
Con T(A)={ aibi / i0 }
239
S-->B
S-->A
A-->
F-->b
B-->aBC
B-->aAE
A-->aBD
A-->aAF
Ahora sí, consideramos el enunciado buscado, sea A un AP entonces es posible construir una
GLC G’ tal que L(G’)=T(A)-{}.
Demostración:
Sea el AP A=(K,,,,q0,Z,{})
Partiendo de A construimos la cuasi-GLC G tal que L(G)=T(A) como se indica arriba.
Y a partir de la cuasi-GLC G construimos la GLC G’ tal que L(G’)=L(G)-{} como se indicó
antes, es decir, eliminando las producciones borradoras de G.
Dado que L(G)=T(A), entonces L(G’)=T(A)-{}. No es necesario pero recomendamos
limpiar la GLC G’.
Ejemplo:
Vamos a continuar el ejemplo de la cuasi-GLC G de antes.
Para eliminar las producciones borradoras de esta cuasi-GLC y construir así la GLC G’
primero calculamos ANULABLES:
B0={A}
B1=B0 {A / A-->uuB0+}={A} {S}={A,S}
B2=B1 {A / A-->u,uB1+}={A,S}
Como B1=B2 entonces B1=ANULABLES={A,S}
Luego G’=({S,A,B,C,D,E,F},{a,b},P’,S)
P’:
S-->B
S-->A
F-->b
B-->aBC
B-->aAE
A-->aBD
A-->aAF
B-->aE borrando A en B-->aAE
A-->aF borrando A en A-->aAF
Nótese que no podemos añadir S--> (borrando A en S-->A pues resulta una producción
borradora).
240
Si queremos podemos continuar la limpieza de la gramática para obtener finalmente
G’=({S,A,F},{a,b},P’,S)
P’:
S --> aF
S --> aAF
A --> aAF
A --> aF
F --> b
Nótese que esta GLC G’ genera L(G)={ aibi / i>0 }=T(A)-{}.
Sin embargo el otro enunciado: Si existe un APe.f. determinístico que acepte L entonces
existe un AP determinístico que acepte L, es falso.
241
Para probar ello mostraremos un lenguaje que sea aceptado por un APe.f. determinístico pero
que no sea aceptado por ningún AP determinístico.
Es claro que el siguiente APe.f. determinístico A es tal que T(A)={a,aa}
A=({q0,qf},{a},Z,X,Y},,q0,Z,{qf})
’:
(q0,a,Z)={(qf,X)}
(qf,a,X)={(qf,Y)}
Ahora mostraremos que si un lenguaje L incluye dos cadenas u,w (uw) tales que u es prefijo
de w (w=uv), ningún AP determinístico acepta L:
Supongamos que el AP A’=(K,,,,q0,Z,{}) es tal que T(A’)=L, en particular acepta tanto u
como w, entonces q0,u,Z|--*(qh,,) con qhK. Veamos qué pasa con w=uv:
q0,uv,Z|--*(qh,v,) pues A’ es determinístico, pero entonces w no será aceptada nunca pues la
pila ya está vacía.
El lenguaje L={a,aa} cumple las condiciones del enunciado y por lo tanto ningún AP
determinístico acepta L.
242
’:
1) ’(q0’,,Z0) = {(q0,ZZ0)}
2) Si (q,c,Y)={(p,)} -c({})- con =, =Y ó =XY
’(q,c,Y) =(q,c,Y)
3) Si (q,c,Y)={(p,X)} -c({})-
’(q,c,Y) = {(pj,)}
’(pj,,W) = {(p,XW)} W({Z0})
donde pj es un nuevo estado (no final)
4) Si (q,c,Y)={(p,XU)} -c({})-
’(q,c,Y) = {(pj,)}
’(pj,,W) = {(ph,UW)} W({Z0})
’(ph,,U) = {(p,XU)}
donde pj,ph son nuevos estados (no finales)
K’ = K {q0’} {todos los nuevos estados añadidos}
Ejemplo:
Sea el APe.f A1=({q0,q1,q2},{a,b,c,d,e},{Z,B,C,D,E},1,q0,Z,{q2})
1:
1(q0,a,Z)={(q1,BDE)}
1(q1,b,B)={(q1,C)}
1(q1,c,C)={(q1,)}
1(q1,d,D)={(q1,)}
1(q1,e,E)={(q2,ZZZZ)}
Construimos así el APe.f A=(K,{a,b,c,d,e},{Z,B,C,D,E},,q0,Z,{q2}) en forma normal 1.
K={q0,q1,q2,p1,p2,p3}
:
De Viene
1(q0,a,Z)={(q1,BDE)} (q0,a,Z)={(p1,DE)}
(p1,,D) = {(q1,BD)}
1(q1,b,B)={(q1,C)} (q1,b,B)={(q1,C)}
1(q1,c,C)={(q1,)} (q1,c,C)={(q1,)}
1(q1,d,D)={(q1,)} (q1,d,D)={(q1,)}
1(q1,e,E)={(q2,ZZZZ)} (q1,e,E)={(p2,ZZ)}
(p2,,Z) = {(p3,ZZ)}
(p3,,Z) = {(q2,ZZ)}
243
’:
De Viene
’(q0’,,Z0) = {(q0,ZZ0)}
(q0,a,Z)={(p1,DE)} ’(q0,a,Z) = {(p4,)}
’(p4,,Z) = {(p5,EZ)}
’(p4,,B) = {(p5,EB)}
’(p4,,C) = {(p5,EC)}
’(p4,,D) = {(p5,ED)}
’(p4,,E) = {(p5,EE)}
’(p4,,Z0) = {(p5,EZ0)}
’(p5,,E) = {(p1,DE)}
(p1,,D) = {(q1,BD)} ’(p1,,D) = {(q1,BD)}
244
Sea A un APe.f. A con |F| > 1, es decir con más de un estado final, entonces es posible
construir un otro APe.f. A’ tal que |F’| = 1 y T(A)=T(A’).
Demostración:
A partir de A construimos un AP A’’ como se indicó antes.
A partir de A’’ construimos un APe.f. A’ como se indicó antes.
Es obvio que A’ tiene F’={qf} un solo estado final, las demostraciones anteriores prueban que
T(A)=T(A’).
Ofrecemos la siguiente alternativa.
Sea el APe.f. A=(K,,,,q0,Z,F) -Z’; q0’,qfK -, construimos así el APe.f.
A’=(K{q0’,qf},,{Z’},’,q0’, Z’,F’)
F’ = {qf }
’:
1)’(q0’,,Z’) = {(q0,ZZ’)}
2) ’(qi,c,X) = (qi,c,X) qiK, c( {}), X
3) ’(qj,,X) = {(qf,)} qjF, X{Z’}
Nótese que el inciso 2 nos dice que copiemos .
Ejemplo:
Sea el APe.f A=({q0,q1,q2,q3},{a,b,c},{Z},,q0,Z,{q2,q3})
:
(q0,a,Z)={(q1,Z)}
(q1,b,Z)={(q2,Z)}
(q2,c,Z)={(q3,Z)}
Construimos así el APe.f A’=({q0,q1,q2,q3,q0’,qf},{a,b,c},{Z,Z’},’,q0’,Z’,{qf})
’:
’(q0’,,Z’)={(q0,ZZ’)}
’(q0,a,Z)={(q1,Z)}
’(q1,b,Z)={(q2,Z)}
’(q2,c,Z)={(q3,Z)}
’(q2,,Z) = {(qf,)}
’(q2,,Z’) = {(qf,)}
’(q3,,Z) = {(qf,)}
’(q3,,Z’) = {(qf,)}
245
CAPÍTULO 14. CERRADURA: el caso libre de contexto
Unión
Los lenguajes libres de contexto son cerrados respecto de la operación unión.
Sean G1=(N1,T1,P1,S1) y G2=(N2,T2,P2,S2) dos GLC’s tales que L(G1)=L1 y L(G2)=L2 con
(N12 S(N1N2).
Entonces podemos construir una GLC G tal que L(G)=L1L2.
Demostración:
Construimos así la GLC G=(N1N2{S},T1T2,P,S)
P = {S-->S1} (1)
{S-->S2} (2)
P1 P2 (3)
L(G)=L1L2. En efecto, sea wL1L2, es decir, S1=>*w en P1 ó S2=>*w en P2. Es claro que
S=>S1=>*w por 1 para el primer paso; por hipótesis y P1P -por 3- para el resto. Ó
S=>S2=>*w por 2 para el primer paso; por hipótesis y P2P -por 3- para el resto.
*
Es decir, S=> w en G, es decir, wL(G).
Ejemplo:
Sea el lenguaje libre de contexto L1=L(G1)={aibj / i>j0} donde G1=({S1},{a,b},P1,S1)
P1:
S1-->aS1b
S1-->aS1
S1-->a
246
P:
S-->S1
S-->S2
S1-->aS1b
S1-->aS1
S1-->a
S2-->aS2b
S2-->S2b
S2-->b
G es tal que L(G)=L1L2={aibj / i>j0}{aibj / 0i<j}. Nótese que si tenemos el lenguaje
L’={ aibj / ij, i+j>0 }, este puede caracterizarse como L’={aibj / i>j0}{aibj / 0i<j}, que en
otros términos podríamos anotar así L’={aibj / i>j}{aibj / i<j} ó así L’={aibj / ij}.
Ejemplo:
Sea A1=({q0,q1},{a},{Z1},1,q0,Z1,{q1})
1: 1(q0,a,Z1)={(q1,Z1)}
Sea A2=({p0,p1},{b},{Z2},2,p0,Z2,{p1})
2: 2(p0,b,Z2)={(p1,Z2)}
Construimos así el APe.f. A=({q0,q1,p0,p1,r0},{a,b},{Z1,Z2,Z},,r0,Z,{q1,p1})
:
(r0,,Z)={(q0,Z1),(p0,Z2)}
(q0,a,Z1)={(q1,Z1)}
(p0,b,Z2)={(p1,Z2)}
247
Concatenación
Los lenguajes libres de contexto son cerrados respecto de la operación concatenación.
Sean G1=(N1,T1,P1,S1) y G2=(N2,T2,P2,S2) dos GLC’s tales que L(G1)=L1 y L(G2)=L2 con
(N12 S(N1N2), entonces podemos construir una GLC G tal que L(G)=L1.L2.
Demostración:
Construimos así la GLC G=(N1N2{S},T1T2,P,S)
P = { S -->S1S2 } (1)
P1 P2 (2)
L(G)=L1.L2.
En efecto, sea wL1.L2 -w=uv-, es decir, S1=>*u en P1, S2=>*v en P2. Es claro que
S=>S1S2 por 1
*
=> uS2 por hipótesis y P1P -por 2-
=>*uv por hipótesis y P2P -por 2-
Es decir, S=>*w en G pues w=uv, es decir, wL(G).
Inversamente, sea wL(G), es decir, S=>*w en G. Ninguna producción de 2 incluye a S, luego
el primer paso de dicha derivación es S=>S1S2 -por 1-, además dado que (N1N2)={}, no es
posible que el uso de producciones “se mezcle” y por tanto efectuando una derivación más a
la izquierda S1S2=>*uS2 se hace sólo con P1, es decir S1=>*u en P1; y a partir de ahí uS2=>*uv
se hace sólo con P2, es decir S2=>*v en P2. Resulta pues que si S=>*uv=w, uL1 y vL2, es
decir, wL1.L2.
Ejemplo:
Sea el lenguaje libre de contexto L1=L(G1)={aibj / i>j0} donde G1=({S1},{a,b},P1,S1)
P1:
S1-->aS1b
S1-->aS1
S1-->a
Sea el lenguaje libre de contexto L2=L(G2)={aibj / 0i<j} donde G2=({S2},{a,b},P2,S2)
P2:
S2-->aS2b
S2-->S2b
S2-->b
Construimos así la GLC G=({S,S1,S2},{a,b},P,S)
P:
S-->S1S2
S1-->aS1b
S1-->aS1
S1-->a
S2-->aS2b
S2-->S2b
S2-->b
248
Mostraremos la construcción con APe.f.:
Sean A1=(K1,1,1,1,q0,Z1,F1) y A2=(K2,2,2,2,p0,Z2,F2) -(K1K2)={}, (12)={},
Z(12), r0(K1K2)– dos APe.f tales que T(A1)=L1 y T(A2)=L2, construimos así el APe.f.
A=(K1K2{r0}, 12, 12{Z}, , r0, Z, F2)
:
1)(r0,,Z) = { (q0,Z1Z) }
2) (qi,c,X) = 1(qi,c,X) qiK1, c(1{}), X1
3) (qi,,X) = { (p0,Z2X) } qiF1, X(1{Z})
4) (pj,c,Y) = 2(pj,c,Y) pjK2, c(2{}), Y2
Nótese que el inciso 2 nos dice que copiemos 1 y que el inciso 4 nos dice que copiemos 2.
Además, trabajando con w=uv,
uv[L1.L2] si y sólo si uv[T(A1).T(A2)] si y sólo si
(q0,u,Z1)|--*(qf,,) qfF1 y (p0,v,Z2)|--*(ph,,) phF2 si y sólo si
r0,uv,Z|--(q0,uv,Z1Z)|--*(qf,v,Z) qfF1 por 1,2; y
(qf,v,Z)|--(p0,v,Z2Z)|-- (ph,,Z) phF2
*
por 3,4 si y sólo si en A
r0,uv,Z|--*(rj,,) rjF si y sólo si
uvT(A)
Ejemplo:
Sea A1=({q0,q1},{a},{Z1},1,q0,Z1,{q1})
1: 1(q0,a,Z1)={(q1,Z1)}
Sea A2=({p0,p1},{b},{Z2},2,p0,Z2,{p1})
2: 2(p0,b,Z2)={(p1,Z2)}
Construimos así el APe.f. A=({q0,q1,p0,p1,r0},{a,b},{Z1,Z2,Z},,r0,Z,{p1})
:
(r0,,Z)={(q0,Z1Z)}
(q0,a,Z1)={(q1,Z1)}
(q1,,Z1)={(p0,Z2Z1)}
(q1,,Z)={(p0,Z2Z)}
(p0,b,Z2)={(p1,Z2)}
249
Nótese que el inciso 2 nos dice que copiemos 1.
Nótese que el inciso 4 nos dice que copiemos 2.
Además, trabajando con w=uv,
uv[L1.L2] si y sólo si uv[T(A1).T(A2)] si y sólo si
(q0,u,Z1)|--*(qi,,) qiK1 y (p0,v,Z2)|--*(pj,,) pjK2 si y sólo si
r0,uv,Z|--(q0,uv,Z1Z)|--*(qi,v,Z) qiK1 por 1,2; y
(qi,v,Z)|--(p0,v,Z2)|--*(pj,,) pjK2 por 3,4 en A si y sólo si
r0,uv,Z|--*(rj,,) rjK si y sólo si
uvT(A)
Ejemplo:
Sea A1=({q0,q1},{a},{Z1},1,q0,Z1,{q1})
1: 1(q0,a,Z1)={(q1,)}
Sea A2=({p0,p1},{b},{Z2},2,p0,Z2,{p1})
2: 2(p0,b,Z2)={(p1,)}
Construimos así el APe.f. A=({q0,q1,p0,p1,r0},{a,b},{Z1,Z2,Z},,r0,Z,{p1})
:
(r0,,Z)={(q0,Z1Z)}
(q0,a,Z1)={(q1,)}
(q0,,Z) = {(p0,Z2)}
(q1,,Z) = {(p0,Z2)}
(p0,b,Z2)={(p1,)}
Estrella de Kleene
Los lenguajes libres de contexto son cerrados respecto de la operación estrella de Kleene.
En el caso de GLC’s hablamos de la cruz de Kleene pues no manjean .
Sea G1=(N1,T1,P1,S1) una GLC tal que L(G1)=L con SN1, entonces podemos construir una
GLC G tal que L(G)=L+.
Demostración:
Construimos así la GLC G=(N1{S},T1,P,S)
P = { S --> S1S } (1)
{ S --> S1 } (2)
P1 (3)
L(G)=L+. En efecto, sea wL+, es decir, w=w1...wm con m>0, S1=>*wi. Es claro que
S=>*S1...S1 por 1 y 2, S deriva una cadena de m (m>0) símbolos S1
=>*w1S1...S1 por hipótesis y P1P -por 3- iniciando una derivación más a la izquierda
=>*w1...wm por hipótesis y P1P -por 3-
Luego, wL(G).
Inversamente, sea wL(G), es decir, S=>*w en G. La forma en que se construye P indica que
esta derivación debe ser de la forma S=>*S1...S1S=>*S1...S1=>*w1...wm
250
Donde cada wi se deriva de S1, es decir, cada wiL. Luego, si S=>*w en G, w=w1...wm, con
wiL, es decir, wL+.
Ejemplo:
Sea el lenguaje libre de contexto L1=L(G1)={aibj / i>j0} donde G1=({S1},{a,b},P1,S1)
P1:
S1-->aS1b
S1-->aS1
S1-->a
Construimos así la GLC G=({S,S1},{a,b},P,S)
P:
S-->S1S
S-->S1
S1-->aS1b
S1-->aS1
S1-->a
251
Una construcción alternativa es A=(K1{r0}, 1, 1{Z}, , r0, Z, {r0})
:
1)(r0,,Z) = { (q0,Z1Z) }
2) (qi,c,X) = 1(qi,c,X) qiK1, c(1{}), X1
3) (qi,,X) = { (r0,ZX) } qiF1, X(1{Z})
Ejemplo:
Sea A1=({q0,q1},{a},{Z1},1,q0,Z1,{q1})
1: 1(q0,a,Z1)={(q1,Z1)}
Construimos así el APe.f. A=({q0,q1,r0,r1},{a},{Z1,Z},,r0,Z,{r0})
:
(r0,,Z) = {(q0,Z1Z)}
(q0,a,Z1)={(q1,Z1)}
(q1,,Z1)={(r1,Z1)}
(q1,,Z)={(r1,Z)}
(r1,,Z1)={(r1,)}
(r1,,Z)={(r0,Z)}
252
Ejemplo:
Sea A1=({q0,q1},{a},{Z1},1,q0,Z1,{})
1: 1(q0,a,Z1)={(q1,)}
Construimos así el APe.f. A=({q0,q1,r0},{a},{Z1,Z},,r0,Z,{})
:
(r0,,Z) = { (q0,Z1Z), (r0,) }
(q0,a,Z1)={(q1,)}
(q0,,Z) = {(r0,Z)}
(q1,,Z) = {(r0,Z)}
En efecto, es claro que L1={a,b} y L2={b,c} son lenguajes libre de contexto, pues son finitos y
de ahí regulares -es obvio que toda GR es una GLC-. L=(L1L2)={b}, que es finito y de ahí
regular y por lo tanto libre de contexto.
Por otro lado, L1={aibicj / i+j>0} y L2={aibjcj / i+j>0} son lenguajes libres de contexto pues
L1=L(G1) con G1=({S,X,C},{a,b,c},P1,S)
P1:
S-->XC
S-->X
S-->C
X-->aXb
X-->ab
C-->cC
C-->c
Y L2=L(G2) con G2=({Z,Y,A},{a,b,c},P2,Y)
P2:
Z-->AY
Z-->A
Z-->Y
Y-->bXc
Y-->bc
A-->aA
A-->a
En este caso L=(L1L2)={ajbjcj / j>0}, en el siguiente capítulo demostraremos que este
lenguaje no es libre de contexto.
253
Para la diferencia: con los lenguajes libre de contexto L1={a,b} y L2={b,c}, L=(L1-L2)={a}
que es finito y de ahí regular y por lo tanto libre de contexto.
Por otro lado, L1={aibicj / i+j>0} y L2={aibjck / jk, i+j+k>0} son libres de contexto pues
L1=L(G1) con G1 como antes y L2=L(G2) con G2=({Z,A,W,S1,S2},{a,b},P2:,Z)
P2:
Z-->A
Z-->W
Z-->AW
W-->S1
W-->S2
S1-->bS1c
S1-->bS1
S1-->b
S2-->bS2c
S2-->S2c
S2-->c
A-->aA
A-->a
Ahora L=(L1-L2)={ajbjcj / j>0} (esto puede verse más rápidamente recordando que
L1-L2=L1L2c, L2c representa el complemento de L2), en el siguiente capítulo demostraremos
que este lenguaje no es libre de contexto.
Para el complemento: Supongamos que los lenguajes libres de contexto son cerrados respecto
de la operación complemento. Sean L1 y L2 dos lenguajes libres de contexto, sean L3=L1c y
L4=L2c sus complementos (libres de contexto, por el supuesto), entonces L5=L3L4 también es
libre de contexto (por la cerradura para la unión). Luego L= L5c también es libre de contexto
(por el supuesto). Pero L=(L1L2), de modo que los lenguajes libres de contexto son cerrados
respecto de la operación intersección. Sabemos que esto falso, lo muestra que nuestro
supuesto está equivocado.
254
T(A)=[T(A1)T(A2)].
En efecto, mostraremos por inducción sobre el número de movimientos que si ([q0,p0],w,Z)|--
*
([qj,ph],,) en A entonces (q0,w,Z)|--*(qj,,) en A1 y 2*(p0,w)=ph.
Caso base: Nótese que por ser un APe.f se puede alcanzar un estado final con cero
movimientos si la cadena de entrada es la vacía y si el estado inicial es final. Sea pues,
([q0,p0],w,Z)|--*([qj,ph],,) en cero movimientos, por lo cual [q0,p0]=[qj,ph], w= y =Z.
Entonces es obvio que (q0,w,Z)|--*(qj,,) en A1 por la reflexividad de |--* y 2*(p0,w)=ph por
definición de 2*.
Hipótesis inductiva: El enunciado es cierto para menos de k movimientos.
Paso inductivo: Sea que ([q0,p0],w,Z)|--*([qj,ph],,) en k movimientos. Desglosémoslos en el
último movimiento y el resto, con w=uc -c({})-, así:
([q0,p0],uc,Z)|--*([qi,pg],c,X)|--([qj,ph],,) donde = y el último movimiento ha utilizado
la regla ([qj,ph],)([qi,pg],c,X), esta regla está presente porque (qj,)1(qi,c,X) y
2(pg,c)=ph si c (si c=, pg=ph). Además, ([q0,p0],uc,Z)|--*([qi,pg],c,X) se hace en menos de
k movimientos, es decir, ([q0,p0],u,Z)|--*([qi,pg],,) con =X se hace en menos de k
movimientos, por hipótesis inductiva resulta que (q0,u,Z)|--*(qi,,) en A1 y 2*(p0,u)=pg.
Pero entonces en A1 es posible (q0,uc,Z)|--*(qi,c,X)|--(qj,,) y en A2 es posible
2*(p0,uc)=2(2*(p0,u),c)=2(pg,c)=ph (si c=, 2*(p0,uc)=2*(p0,u)=pg=ph).
Es decir, (q0,w,Z)|--*(qj,,) en A1 y 2*(p0,w)=ph -pues w=uc, =.
255
2(pg,a)=ph permiten, por 1, que ([qj,ph],)([qi,pg],a,X). Luego, en A es posible
([q0,p0],ua,Z)|--*([qi,pg],a,X)|--([qj,ph],,), es decir, ([q0,p0],w,Z)|--*([qj,ph],,) pues w=ua,
=.
Hemos probado que ([q0,p0],w,Z)|--*([qj,ph],,) en A si y sólo si (q0,w,Z)|--*(qj,,) en A1 y
2*(p0,w)=ph. Con qjF1 y phF2, el enunciado dice que wT(A) si y sólo si wT(A1) y
wT(A2).
Ejemplo:
Sea el AFD A2=({p0},{a},2,p0,{p0})
2: 2(p0,a)=p0
Sea el APe.f. A1=({q0,q1},{a},{Z},,q0,Z,{q1})
1:
1(q0,a,Z)={(q1,Z)}
1(q1,a,Z)={(q0,Z)}
Es importante hacer resaltar, para ello basta ver la forma de construir A, que si el APe.f. A1 es
determinístico, el APe.f resultante A es también determinístico.
Una interesante construcción alternativa parte de una GLC limpia G=(N,T,P,S) y de un AFD
A=(K,T,,q1,F) para construir la GLC G’ tal que L(G’)=L(G)T(A) así:
G’=(N’,T,P’,S’)
N’={S’} { Ypq / Y(NT); p,qK }
P’:
1) S’-->Sq1p pK
pq pr1 r1r2
2) Y -->X1 X2 ...Xm r(m-1)q
si Y-->X1...XmP; p,r1,...,r(m-1),qK
3) apq-->a si (p,a)=q
Ejemplo:
Sea el AFD A=({q1},{a,b},,q1,{q1})
: (q1,a)=(q1,b)=q1
Sea la GLC G=({S},{a,b},P,S)
P:
S-->aSb
S-->ab
256
N’={S’, Sq1q1, aq1q1, bq1q1}
P’:
S’-->Sq1q1
Sq1q1-->aq1q1Sq1q1bq1q1
Sq1q1-->aq1q1bq1q1
aq1q1-->a
bq1q1-->b
Para la diferencia: sean L1=T(A1) A1 un APe.f. y L2=T(A2) A2 un AFD, entonces podemos
construir un APe.f A tal que T(A)=(L1-L2). En efecto, sabemos que los lenguajes regulares son
cerrados respecto de la operación complemento, es decir L2c es regular.
(L1-L2)=(L1L2c), es decir, la diferencia entre un lenguaje libre de contexto y uno regular no
es sino la intersección entre un lenguaje libre de contexto y otro regular, lo que –como
acabamos de ver- es libre de contexto.
Debemos pues construir otro APe.f. tal que consuma toda su entrada pero siga siendo
determinístico. Para ello definiremos al par (q,Y) con qK,Y como cíclico si
(q,,Y)|--+(q,,Y) con ,*. Si desde la d.i. inicial logramos accesar a otra d.i. que
tenga a q como estado actual y a Y como el tope de la pila, entonces el APe.f. A puede
ingresar a una secuencia infinita de movimientos de tipo 2, atravesando posiblemente por
estados finales incluso sin consumir toda su entrada.
257
Sea A=(K,,,,q0,Z,F) el APe.f. determinístico inicial con q0’,qe,qmK y Z0, a partir de él
construimos así otro APe.f A’=(K {q0’,qe,qm},, {Z0},’,q0’,Z0,F {qe})
’:
1) ’(q0’,,Z0) = {(q0,ZZ0)}
2) ’(q,a,Z0) = {(qm,Z0)} qK, a
3) ’(q,a,Y) = {(qm,Y)} si |(q,a,Y)+(q,,Y)|=0 qK, a, Y
4) ’(qm,a,Y) = {(qm,Y)} a, Y{Z0}
5) Calculamos todos los pares cíclicos.
Para cada par cíclico (q,Y) calculamos todos los estados qj a los que se llega desde el estado q
–con el tope Y- solamente con -transiciones, es decir, con qK,Y, todos los estados qj
tales que (q,,Y)|--*(qj,,) *:
’(q,,Y) = {(qm,Y)} si ningún qjF
’(q,,Y) = {(qe,Y)} si algún qjF
6) ’(qe,,Y) = {(qm,Y)} Y{Z0}
7) ’(q,a,Y) =(q,a,Y) si ’(q,a,Y) no se ha definido en 2,3 ó 5 qK, a{}, Y
A’ no sólo consumirá toda su entrada, sino que ya no tiene ningún par cíclico, de manera que
no ingresará a secuencias infinitas de movimientos, además T(A)=T(A’).
Ahora sí retornamos al enunciado inicial, a partir del APe.f A=(K,,,,q0,Z,F) que no tiene
pares cíclicos (y que consume toda su entrada) construimos otro APe.f A’ tal que
T(A’)=*-T(A), es decir A’ acepta el complemento de A.
A’=(K’,,,’,q0’,Z,F’)
K’ = {[q,r] / qK, r=1,2,3}
q0’ = [q0,1] si q0F
[q0,2] si q0F
F’={ [q,3] / qK }
’:
1) Si (q,,Y)={(p,)} y pF
’([q,1],,Y) = {([p,1],)}
’([q,2],,Y) = {([p,1],)}
2) Si (q,,Y)={(p,)} y pF
’([q,1],,Y) = {([p,1],)}
’([q,2],,Y) = {([p,2],)}
3) Si (q,a,Y)={(p,)} y pF
’([q,2],,Y) = {([q,3],Y)}
’([q,1],a,Y) = ’([q,3],a,Y) = {([p,1],)}
4) Si (q,a,Y)={(p,)} y pF
’([q,2],,Y) = {([q,3],Y)}
’([q,1],a,Y) = ’([q,3],a,Y) = {([p,2],)}
258
Ejemplo:
Sea el APe.f A1=({q0,q1,q2},{a},{Z},1,q0,Z,{q2})
1:
1(q0,a,Z)={(q1,Z)}
1(q1,,Z)={(q2,Z)}
1(q2,,Z)={(q1,Z)}
Es claro que T(A)={a}.
Ahora construiremos otro APe.f. determinístico A que consuma toda su entrada, que no tenga
pares cíclicos y tal que T(A)=T(A1):
A=({q0,q1,q2,p0,qe,qm},{a},{Z,Z0},,p0,Z0,{q2,qe})
:
a) (p0,,Z0)={(q0,ZZ0)} por la regla 1
b) (q0,a,Z0)={(qm,Z0)} por la regla 2
c) (q1,a,Z0)={(qm,Z0)} idem
d) (q2,a,Z0)={(qm,Z0)} idem
la regla 3 no se aplica (todos los estados tienen salidas)
e) (qm,a,Z)={(qm,Z)} por la regla 4
f) (qm,a,Z0)={(qm,Z0)} idem
En A1 los pares cíclicos son (q1,Z) y (q2,Z) pues (q1,,Z)|--+(q1,,Z) y (q2,,Z)|--+(q2,,Z).
Desde q1 con el tope Z podemos llegar a q2(F) y a q1.
Desde q2 con el tope Z podemos llegar a q1 y a q2(F).
g) (q1,,Z)={(qe,Z)} por la regla 5
h) (q2,,Z)={(qe,Z)} idem
i) (qe,,Z)={(qm,Z)} por la regla 6
j) (qe,,Z0)={(qm,Z0)} idem
k) (q0,a,Z)={(q1,Z)} por la regla 7
Partiendo de A construiremos otro APe.f. determinístico A’ talque T(A’)=*-T(A).
A’=(K’,{a},{Z,Z0},’,q0’,Z0,F’)
K’={[p0,1],[q0,1],[q1,1],[q2,1],[qe,1],[qm,1],
[p0,2],[q0,2],[q1,2],[q2,2],[qe,2],[qm,2],
[p0,3],[q0,3],[q1,3],[q2,3],[qe,3],[qm,3]}
q0’=[p0,2]
F’={[p0,3],[q0,3],[q1,3],[q2,3],[qe,3],[qm,3]}
’:
De la transición a) por la regla 2 :
’([p0,1],,Z0)={([q0,1],ZZ0)}
’([p0,2],,Z0)={([q0,2],ZZ0)}
De la transición b) por la regla 4:
’([q0,2],,Z0)={([q0,3],Z0)}
’([q0,1],a,Z0)={([qm,2],Z0)}
’([q0,3],a,Z0)={([qm,2],Z0)}
259
De la transición c) por la regla 4:
’([q1,2],,Z0)={([q1,3],Z0)}
’([q1,1],a,Z0)={([qm,2],Z0)}
’([q1,3],a,Z0)={([qm,2],Z0)}
De la transición d) por la regla 4:
’([q2,2],,Z0)={([q2,3],Z0)}
’([q2,1],a,Z0)={([qm,2],Z0)}
’([q2,3],a,Z0)={([qm,2],Z0)}
De la transición e) por la regla 4:
’([qm,2],,Z)={([qm,3],Z)}
’([qm,1],a,Z)={([qm,2],Z)}
’([qm,3],a,Z)={([qm,2],Z)}
De la transición f) por la regla 4:
’([qm,2],,Z0)={([qm,3],Z0)}
’([qm,1],a,Z0)={([qm,2],Z0)}
’([qm,3],a,Z0)={([qm,2],Z0)}
De la transición g) por la regla 1:
’([q1,1],,Z)={([qe,1],Z)}
’([q1,2],,Z)={([qe,1],Z)}
De la transición h) por la regla 1:
’([q2,1],,Z)={([qe,1],Z)}
’([q2,2],,Z)={([qe,1],Z)}
De la transición i) por la regla 2:
’([qe,1],,Z)={([qm,1],Z)}
’([qe,2],,Z)={([qm,2],Z)}
De la transición j) por la regla 2:
’([qe,1],,Z0)={([qm,1],Z0)}
’([qe,2],,Z0)={([qm,2],Z0)}
De la transición k) por la regla 4:
’([q0,2],,Z)={([q0,3],Z)}
’([q0,1],a,Z)={([q1,2],Z)}
’([q0,3],a,Z)={([q1,2],Z)}
Hemos resaltado en negrita las reglas de transición que sería interesante graficar primero si así
se desea.
Resta indicar si el cálculo de pares cíclicos es computable, es decir, si podemos escribir algún
algoritmo que nos diga, dado un APe.f. determinístico A, cuáles son sus pares cíclicos si
existen. Dicho cálculo en efecto es computable: Para cada par estado,símbolo de la pila (q,Y)
podemos iniciar una serie de -transiciones, si en algún momento ello no es posible es claro
que el par no es cíclico.
260
Sólo nos queda observar si (q,,Y)|--+(q,,Y) en un número posiblemente largo pero
finito de movimientos puesto que el número de estados y el número de símbolos es finito.
Ello se simplifica si A está en forma normal 2, cosa que exigiremos al utilizar la conversión.
261
. Si u o v (o ambas subcadenas) incluyen dos símbolos diferentes, con h=2 por simple
inspección la cadena resultante yu2xv2z no está en L(G) pues tiene símbolos “mezclados” (por
ejemplo a..ab..ba..ab..b), pero el lema dice que esas cadenas están en L(G). Una
contradicción.
. Si u (o v) incluye sólo a’s, con h suficientemente grande –e incluso con h=2- por simple
inspección las cadenas resultantes no están en L(G) pues tienen ij (basta una ‘a’ más para
igualar las m+1 b’s), pero el lema dice que esas cadenas están en L(G). Una contradicción.
. Si ni u ni v incluyen a’s, con h=0 por simple inspección la cadena resultante yxz no está en
L(G) pues tiene ij (o ik) (basta una ‘b’ menos -o una ‘c’ menos - para igualar las m a’s),
pero el lema dice que esas cadenas están en L(G). Una contradicción.
Hemos mostrado que [Lc ({a}*{b}*{c}*)] no es libre de contexto. Es evidente que
({a}*{b}*{c}*) es regular, sabemos que un lenguaje libre de contexto intersectado con un
lenguaje regular es también libre de contexto, luego si Lc fuera libre de contexto, toda la
intersección sería un lenguaje libre de contexto, pero no es el caso, entonces Lc no es libre de
contexto. También sabemos que si un lenguaje es libre de contexto determinístico su
complemento también es libre de contexto determinístico. Así, si L fuera libre de contexto
determinístico, entonces Lc sería también libre de contexto determinístico, pero Lc no es libre
de contexto determinístico (¡ni siquiera es libre de contexto!), luego L=(L1L2) no es libre de
contexto determinístico, que es lo que queriamos probar.
262
El APe.f. determinístico A=({r0,q0,q1,p0,p1},{0,a,b,c},{Z,A,B,C},,r0,Z,{r0,q0,q1,p0,p1}) acepta
L.
:
(r0,0,Z)={(q0,Z)} (q0,a,Z)={(q0,AZ)} (p0,a,A)={(p0,AA)}
(q0,a,A)={(q0,AA)} (p0,b,A)={(p0,A)}
(r0,b,Z)={(p1,B)} (q0,b,A)={(q1,)} (p0,c,A)={(p1,)}
(r0,a,Z)={(p0,AZ)} (q1,b,A)={(q1,)} (p1,c,A)={(p1,)}
(q0,c,A)={(q1,C)} (p1,b,B)={(p1,B)}
(q1,c,A)={(q1,C)}
(q0,c,Z)={(q1,C)}
(q1,c,Z)={(q1,C)}
(q1,c,C)={(q1,C)}
Es decir, ({0}.L1 {0}.L2) es libre de contexto determinístico, pero ello indica que (L1 L2)
es libre de contexto determinístico: en efecto, necesitamos un AP determinístico que acepte
cadenas en (L1 L2), si ya hay un AP determinístico A’ que acepta cadenas en
({0}.L1{0}.L2) entonces podemos utilizar el mismo A’ para reconocer cadenas en (L1 L2)
adicionando a cada entrada el prefijo ‘0’ que es espúreo pero necesario para utilizar A’, con
este artificio el AP determinístico A’ nos sirve bien para reconocer (L1 L2) lo que nos
permite decir que (L1 L2) si es libre de contexto determinístico. Sin embargo hemos ya
probado que (L1 L2) no es libre de contexto determinístico, lo que prueba nuestro enunciado.
263
Pero L* no lo es puesto que si lo fuera entonces el lenguaje [L* ({0}{a}*{b}*{c}*)] también
sería libre de contexto determinístico –por la misma razón de arriba-, como [L*
({0}{a}*{b}*{c}*)] = {0}.L1 {0}.L2 estaríamos diciendo que (L1 L2) es libre de contexto
determinístico -que por lo expuesto arriba- es falso.
264
CAPÍTULO 15. PROBLEMAS DE DECISIÓN: El caso libre de contexto
265
Ello se muestra por inducción sobre j, basta para ello construir el conjunto Bij, es decir, hallar
todos los No Terminales X tales que X=>zij y ver si XBij.
Caso base: j=1. Es evidente que para construir Bi1, es decir, hallar los No Terminales X tales
que X=>zi1 (subcadenas de w que comienzan en la posición i, de longitud 1, esto es zi1=ai ), es
decir, No Terminales que derivan el símbolo de la posición i, basta hallar
Bi1={ XN / X->ai P } y ver si X está en este conjunto.
Hipótesis inductiva: El enunciado es cierto para j<k.
Paso inductivo: Sea j=k(>1). Es claro que X=>zik si y sólo si X=>YW=>zihW=>zihz(i+h)(k-h)
con X-->YWP y 1h<k, Y deriva los primeros h símbolos de zik, W deriva los últimos k-h
símbolos de zik. Por hipótesis inductiva es posible decidir si Y=>zih así como si W=>z(i+h)(k-h),
pues h<k y k-h<k, bastará observar los conjuntos Bih y B(i+h)(k-h). De ahí es posible decidir si
X=>zik, basta construir Bik={ X / X-->YWP, YBih, WB(i+h)(k-h)} –para todas las
combinaciones a que de lugar 1h<k - y ver si X está en este conjunto.
El procedimiento siguiente se desprende de lo que se acaba de anotar:
Para i de 1 a m: Bi1={ XN / X->ai P }
Para j de 2 a m:
Para i de 1 a m-j+1:
Bij={}
Para h de 1 a j-1: Bij=Bij { X / X-->YWP, YBih, WB(i+h)(j-h)}
Es común presentar esta construcción de los conjuntos Bij en una matriz cuadrada B de
dimensión (m X m) de la que sólo se llena una parte triangular como se muestra a
continuación.
Ejemplos:
Sea la GLC en FNCH G=({S,X,Y,A},{a,b},P,S)
P:
S-->XY
X-->XA
Y-->AY
A-->a
X-->a
X-->b
Y-->a
Con la cadena de testeo w=baa=a1a2a3 configuramos la matriz B del modo que se ilustra
enseguida; cada posición i,j representa al conjunto Bij descrito arriba:
Así por ejemplo B21={X / X->a2P}={X / X->aP}={A,X,Y}
X
A,X,Y -
A,X,Y - -
Trabajando con la celda B12 (i=1, j=2, h=1) tenemos B12={ X / X-->YWP, YB11, WB21}
Como B11.B21={X}.{A,X,Y}={XA,XX,XY}, buscamos todas las producciones que tengan
estas partes derechas, y añadimos sus partes izquierdas al conjunto.
266
Trabajando con la celda B22 (i=2, j=2, h=1) tenemos B22={ X / X-->YWP, YB21, WB31}
Como B21.B31={A,X,Y}.{A,X,Y}={AA,AX,AY,XA,XX,XY,YA,YX,YY}, buscamos todas
las producciones que tengan estas partes derechas, y añadimos sus partes izquierdas al
conjunto.
X S,X
A,X,Y X,Y,S -
A,X,Y - -
Trabajando con la celda B13 (i=1, j=3), en este caso h debe ir de 1 a 2(=j-1).
En principio B13={}, para h=1 tenemos:
B13={} { X / X-->YWP, YB11, WB22}
Como B11.B22={X}.{X,Y,S}={XX,XY,XS}, buscamos todas las producciones que tengan
estas partes derechas, y añadimos sus partes izquierdas al conjunto, así B13={S}
Para h=2 tenemos:
B13={S} { X / X-->YWP, YB12, WB31}
Como B12.B31={S,X}.{A,X,Y}={SA,SX,SY,XA,XX,XY}, buscamos todas las producciones
que tengan estas partes derechas, y añadimos sus partes izquierdas al conjunto, finalmente
B13={S,X}, luego la matriz entera es:
X S,X S,X
A,X,Y X,Y,S -
A,X,Y - -
Como la raíz S está en B13 entonces wL(G).
Para la cadena de testeo w=babaa, la matriz final es:
X X,S
A,X,Y -
X X,S S,X - -
A,X,Y Y,X,S - - -
A,X,Y - - - -
Como la raíz S no está en B15 entonces wL(G).
267
Es obvio que si hay una cadena w -|w|<2n- tal que S=>w entonces L(G).
Inversamente, sea L(G), probaremos que w |w|<2n S=>w por reducción al absurdo.
Supongamos que la cadena más pequeña –en longitud- de L(G) es w, con |w|2n-, por el lema
de bombeo podemos reescribirla así w=yuxvz con |uv|>0 y por lo tanto |yxz|<|yuxvz|, por el
supuesto es claro que yxzL(G) pues la cadena más peuqeña es w. Pero por el lema
mencionado con i=0 yxzL(G).
Esta contradicción prueba el enunciado que nos da el conjunto finito de cadenas de prueba
buscado: debemos probar solamente las cadenas de longitud menor que 2n si alguna de ellas,
es aceptada es obvio que L(G), en otro caso L(G)=.
268
Dado un conjunto infinito de cadenas, el lema de bombeo puede ser útil para mostrar que no
es libre de contexto.
Ejemplos:
Mostraremos que L={ajbjcj / j>0} no es libre de contexto, es decir, no hay una GLC G que lo
genere.
Demostración:
Supongamos que L si es libre de contexto, es decir, L=L(G) con |N|=n y G en FNCH.
Es claro que L es infinito y que las cadenas de L tienen longitud 3j, luego hay una cadena
wL(G) tal que |w|2n, por ejemplo para j=2n la cadena w es tal que |w|=3(2n)2n. Por el lema
de bombeo w puede reescribirse así w=yuxvz con |uv|>0 y |uxv|2n, además yuixvizL(G)
para todo i0.
Procedemos a analizar cuál es la forma de la cadena uxv y por lo tanto de u y v:
i) Una posibilidad es que uxv sea una secuencia del mismo símbolo y por lo tanto u y v
también, digamos u=a...a, v=a...a, pero entonces con i=0 la cadena yxz tiene igual número de
b’s y c’s pero tiene menos a’s: por simple inspección dicha cadena no está en L, pero por el
lema de bombeo con i=0 esa cadena sí está en L. Una contradicción.
El razonamiento es idéntico si las secuencias son del símbolo ‘b’ o del símbolo ‘c’, e incluso
si una de las cadenas u o v es vacía.
ii) Otra posibilidad es que uxv sea una secuencia de dos símbolos (no necesariamente de
longitud 2), por ejemplo uxv=a...ab...b, de manera que:
u=a..ab..b y v=b..b, o bien u=a..a y v=a..ab..b, en cualesquiera de estos casos con i=2 tenemos
que la cadena yu2xv2z tiene una secuencia (una subcadena) del tipo a..ab..ba...ab..b
(correspondiente a u2 o bien a v2) que por simple inspección no corresponde a una cadena en
L, pero por el lema de bombeo esta cadena sí está en L. Una contradicción.
Esto sucede incluso si la cadena v es vacía en el primer caso, o si la cadena u es vacía en el
segundo caso.
u=a...a y v=b...b, pero entonces con i=0 la cadena yxz tienen más c’s que a’s y más c’s que
b’s: por simple inspección dicha cadena no está en L, pero por el lema de bombeo con i=0 esa
cadena sí están en L. Una contradicción.
El razonamiento es idéntico si uxv=b...bc...c.
ii) No hay otras formas posibles. Una secuencia de tres símbolos (no necesariamente de
longitud 3) para uxv es imposible pues |uxv|2n, pero (con j=2n) la última ‘a’ de u debe estar a
más de 2n posiciones de la primera ‘c’ (pues de por medio están las 2n ‘b’es).
Estas contradicciones invalidan nuestro supuesto y concluimos que L no es libre de contexto.
269
Procedemos a analizar cuál es la forma de u y v:
i) Si w=bjckdh, es posible que u y v sean secuencias de un sólo símbolo -no necesariamente el
mismo-, luego la conclusión del lema que yuixvizL(G) para todo i0 no se contradice.
ii) Si w=ambjcjdj, es posible que u y v sean secuencias del mismo símbolo ‘a’, en cuyo caso la
conclusión del lema que yuixvizL(G) para todo i0 no se contradice.
Sin embargo, el lema de Ogden sí puede aplicarse.
Sea wL(G) con w=ambjcjdj y m>0. Sea e el entero del lema. Marquemos e símbolos de w así:
w=ambjcjdj. Por el lema podemos descomponer así w=yuxvz, x contiene algún símbolo
marcado, u y v no son simultáneamente libres de símbolos marcados (u.v tiene por lo menos
uno), uxv tiene a lo máse símbolos marcados, yuixvizL(G) para todo i0.
Procedemos a analizar cuál es la forma de la cadena u:
i) Si u incluye una secuencia de dos símbolos marcados b’s y c’s ó c’s y d’s1, u=apb..bc..c,
u=b..bc..c, ó u=c...cd...d con i=2 tenemos que la cadena yu2xv2z tiene una subcadena del tipo
apb..bc..capb..bc..c (ó b..bc..cb..bc..c ó c..cd..dc..cd..d) correspondiente a u2 que por simple
inspección no corresponde a una cadena en L, pero por el lema de Ogden esta cadena sí está
en L. Una contradicción.
ii) Si u incluye una secuencia de tres símbolos marcados el razonamiento es semejante al
anterior.
iii) Si u incluye una secuencia de sólo un símbolo marcado, digamos b’s, tenemos varios
subcasos -el razonamiento es idéntico si la secuencia es del símbolo ‘c’ o del símbolo ‘d’-:
. u=apb...b, con i=2 la cadena yu2xv2z tiene una subcadena del tipo apb..bapb..b que por simple
inspección no corresponde a una cadena en L, pero por el lema de Ogden esta cadena sí está
en L. Una contradicción.
. u=b...b, v=. En este caso con i=0 la cadena yxz tiene a’s, luego igual número de c’s y d’s
pero tiene menos b’s: por simple inspección dicha cadena no está en L, pero por el lema de
Ogden con i=0 esa cadena sí está en L. Una contradicción.
. u=b...b, por la forma de nuestro marcado v contiene una secuencia de un símbolo marcado,
digamos v=d...d. En este caso con i=0 la cadena yxz tiene a’s y luego más c’s que b’s y más
c’s que d’s: por simple inspección no corresponde a una cadena en L, pero por el lema de
Ogden esta cadena sí está en L. Una contradicción. Pasa algo semejante con v=d...d.
Si v=b...b con i=0 la cadena yxz tiene a’s, luego igual número de c’s y d’s pero tiene menos
b’s: por simple inspección dicha cadena no está en L, pero por el lema de Ogden con i=0 esa
cadena sí está en L. Nuevamente una contradicción.
iv) Si u no incluye símbolos marcados, u=ap ó u=. Por el lema sabemos que x contiene por lo
menos un símbolo marcado, entonces por la forma de nuestro marcado v debe ser de sólo
símbolos marcados, si es una secuencia de dos o tres símbolos marcados con i=2 la cadena
yu2xv2z tiene una subcadena del tipo c..cd..d, si es una secuencia de sólo un símbolo marcado
con i=0 la cadena yxz tendrá a’s y luego menos de un símbolo que de los otros dos: en ambos
casos por simple inspección dichas cadenas no están en L, pero por el lema de Ogden sí lo
están. Una contradicción.
v) No hay otras formas posibles.
Estas contradicciones invalidan nuestro supuesto y concluimos que L no es libre de contexto.
270
L= { aibicj / i≠j } no es libre de contexto.
Demostración:
Supongamos que L sí es L.C., es decir, L=L(G) con G=(N,T,P,S) una GLC en FNCH con
|N|=n
𝑛 𝑛 𝑛 𝑛
Sea w = 𝑎2 𝑏 2 𝑐 2 !+2
Sabemos que w se puede reescribir así w = yuxvz
Sabemos que |uxv|≤ 2n; y que |uv|> 0
Posibles formas de uxv, y por lo tanto posibles forma de u,v:
- Si uxv contiene sólo a’s. Entonces con i=0 en yuixviz habrán menos a’s que b’s.
El lema dice que yuixviz está en L(G) pero la simple inspección muestra que no.
- Idem con sólo b’s.
- Idem si uxv tiene b’s y c’s (habrán menos b’s que a’s).
- Idem si uxv es tal que u=ak, v=bk’ (k≠k’).
- Si uxv es tal que u=ak, v=bk, con k≤2n. w = yakxbkz
De modo que en yxz hay 2n-k a’s; 2n-k b’s; 2n!+2n c’s
𝑛 𝑛
Haciendo i=[2n!+k]/k tenemos que yuixviz=y𝑎2 !+𝑘 x𝑏 2 !+𝑘 z
𝑛 𝑛 𝑛 𝑛 𝑛 𝑛
Es decir yuixviz=𝑎2 !+2 𝑏2 !+2 𝑐 2 !+2
Que claramente no está en L.
Nótese que el i que asumimos tiene el factorial para ser necesariamente un entero.
- Si uxv=ck, entonces no es seguro que al hacer i=0, o bombearlo, las cadenas resultantes no
estén en L (obteniendo con ello una contradicción). El Lema de bombeo falla.
Sin embargo, con el Lema de Ogden podemos eliminar el caso de sólo c’s.
𝑛+1 𝑛+1 𝑛+1 𝑛+1
Sea w = 𝑎2 𝑏 2 𝑐 (2 )!+2
Marquemos todas las a’s en rojo de w.
De modo que:
- Si uxv contiene sólo a’s. Entonces con i=0 en yuixviz habrán menos a’s que b’s.
El lema dice que yuixviz está en L(G) pero la simple inspección muestra que no.
- uxv no puede contener sólo b’s o sólo c’s (o sólo b’s y c’s): pues u,v contienen por lo menos
un símbolo marcado.
- Si u (ó v) contiene dos símbolos: con i=2 habría mezclas que no están en L
- Si uxv es tal que u tiene sólo a’s y la subcadena v incluye sólo c’s:
con i=0 habrán menos a’s que b’s.
- Si uxv es tal que u=ak, v=bk’ (k≠k’): con i=0 habrá un número desigual de a’s y b’s.
- Si uxv es tal que u=ak, v=bk, con 2k≤2n+1, es decir, k≤2n. w = yakxbkz
De modo que en yxz hay 2n+1-k a’s; 2n+1-k b’s; 2n+1!+2n+1 c’s
𝑛+1 𝑛+1
Haciendo i=[2n+1!+k]/k tenemos que yuixviz=y𝑎2 !+𝑘 x𝑏 2 !+𝑘 z
𝑛+1 𝑛+1 𝑛+1 𝑛+1 𝑛+1 𝑛+1
Es decir yuixviz=𝑎2 !+2 𝑏 2 !+2 𝑐 2 !+2
Que claramente no está en L.
Nótese que el i que asumimos tiene el factorial para ser necesariamente un entero.
271
Gramáticas LL y LR
Hemos visto el algoritmo CYK y el de Earley para decidir si una cadena está o no en L(G),
dicho de otro modo, para reconocer si la cadena dada está o no en el lenguaje que representa
(genera) la gramática G.
Aunque el reconocimiento más propiamente es parte de estudios sobre compilación (diseño de
compiladores, análisis léxico, etc.) aprovecharemos su mención para presentar una noción de
las gramáticas LL y LR.
Supongamos que se tiene el conjunto de producciones P={S-->aSb,S-->Y,Y-->ab,S-->ab} y
queremos esgrimir un algoritmo que para la cadena w -por ejemplo w=aabb- nos diga si hay o
no una derivación S=>*w:
La construcción de analizadores sintácticos se ocupa precisamente de ello: cómo diseñar un
reconocedor lo más eficientemente posible. Fíjese que una alternativa elemental es contruir un
autómata de pila a partir de la gramática –según se vio- y dejar que dicho autómata reconozca
o no la cadena w. En función de los problemas que aparezcan puede ser útil variar la
construcción del autómata, mejorarlo en algún sentido o bien construir otra GLC que
minimice los problemas.
Es claro que el algoritmo que estamos considerando tendrá que leer la cadena de entrada w
para ver si es o no generada en G, es común hacerlo revisando los símbolos de izquierda a
derecha.
Con la gramática y la cadena de ejemplo podemos pensar que nuestro algoritmo leerá una “a”
y empezará la derivación en “S”, enseguida tendrá que enfrentar el problema de utilizar
alguna producción: puede buscar todas las que tengan como parte izquierda “S” intentar
fortuna con alguna elegida al azar y si se deriva w (en base a una serie de pasos de derivación)
terminar con éxito, sino retroceder hasta la (errónea) decisión tomada e intentar con otra.
Nótese que si P={S-->aSb,S-->ab,S-->dY,Y-->cc} y w=aabb, una decisión mejor se tomará
seleccionando sólo las producciones que tengan como parte izquierda “S” y “a” como cabeza
de la parte derecha.
Si nos permitimos preanalizar, es decir, leer un símbolo más a la derecha del que estamos
revisando, las cosas podrían mejorar en este ejemplo, pues si el siguiente símbolo a una “a” es
otra “a”, es claro que sólo la producción “S-->aSb” puede ser útil para intentar una derivación.
Una exigencia fuerte es que no tengamos necesidad de retroceder para tomar otra decisión
sino hacer nuestro algoritmo tan ingenioso que cada decisión sea la buena (si w es generada, e
incluso si no es generada), es decir, que haya determinismo.
En otros casos, es imprescindible reducir los problemas y tomar la decisión buena requiere
leer no uno sino 2 (o bien k) símbolos más a la derecha del que se escudriña.
Si exigimos una derivación más a la izquierda, a los algoritmos que tienen este
comportamiento (tomando siempre buenas decisiones) los llamaremos analizadores sintácticos
LL(k) –la primera L es por left to right (leer los símbolos de entrada de izquierda a derecha) y
la segunda L es por leftmost derivation (derivación más a la izquierda)-.
No siempre es posible construir uno de estos para una GLC (e incluso para un lenguaje dado),
por ejemplo para el lenguaje L={aibi / i>0}{ai / i>0} no hay un analizador LL(k).
272
Una GLC LL es aquella que admite la construcción de un (algoritmo) analizador sintáctico LL
con la peculiaridad que las producciones se usan en el sentido ParteIzquierda-->ParteDerecha,
es decir, se busca una derivación que parte del símbolo raíz hasta la cadena de entrada w (top-
down o descendente).
Por otro lado en los analizadores sintácticos LR(k) –la primera L es por left to right (leer los
símbolos de entrada de izquierda a derecha)- lo que se busca es una derivación más a la
derecha (la segunda R es precisamente por rightmost derivation), la k tiene una significación
análoga. Una GLC LR es aquella que admite la construcción de un (algoritmo) analizador
sintáctico LR donde las producciones se usan en el sentido ParteDerecha-->ParteIzquierda, es
decir, se busca una derivación que parte de la cadena de entrada w hasta el símbolo raíz
(bottom-up o ascendente).
Ahora queda el problema de reconocer si una GLC es LL o LR, o el más fuerte de construir
una GLC de uno de estos dos tipos directamente (o a partir de otra dada):
En principio diremos que una GLC es LL si es LL(k), y es LR si es LR(k) para algún k.
Denotaremos por PRIMEROSk() a los primeros k Terminales con que empiezan las cadenas
derivables desde , PRIMEROSk()={u / =>*u con |u|=k ó =>*u con |u|<k}
Sea G una GLC limpia, aquí sólo consideraremos derivaciones más a la izquierda.
Diremos que G es LL(k) si
i) S=>*wA=>w=>*w
ii) S=>*wA=>w=>*w
iii) PRIMEROSk()=PRIMEROSk()
implican que =.
Sea G=(N,T,P,S) una GLC y sea G’=(N{S’},T,P{S’-->S},S’) donde S’ es un nuevo No
Terminal, aquí sólo consideraremos derivaciones más a la derecha.
Diremos que G es LR(k) si
i) S’=>*Aw=>w
ii) S’=>*Bx=>y
iii) PRIMEROSk(w)= PRIMEROSk(y)
implican que Ay=Bx con =, y=x.
273
CAPÍTULO 16. CONVERSIONES GENÉRICAS Y CERRADURA:
El caso sensible al contexto
274
Y1Y2Y3...Yn-1Yn --> WY2Y3...Yn-1Yn
WY2Y3...Yn-1Yn --> Wq2Y3...Yn-1Yn
Wq2Y3..Yn-1Yn --> Wq2q3Y4...Yn-1Yn
... ... ...
Wq2q3q4...qn-2Yn-1Yn --> Wq2q3q4...qn-2qn-1Yn
Wq2q3q4...qn-1Yn --> Wq2q3q4...qn-1qnqn+1...qm
Wq2q3q4...qn-1qnqn+1...qm --> q1q2q3q4...qn-1qnqn+1...qm
Donde hemos resaltado en negrita el No Terminal en la parte izquierda (A) que se reemplaza
por la subcadena en la parte derecha (), de manera que todas estas nuevas producciones están
en el formato A--> cuyo contexto y es evidente. Por ejemplo en la primera
producción =, A=Y1, =Y2Y3...Yn-1Yn, =W.
Fíjese que la parte derecha de la primera producción es la parte izquierda de la segunda; la
parte derecha de la segunda producción es la parte izquierda de la tercera; etc.
Fíjese que todas reemplazan un No Terminal (A) por la subcadena de un símbolo, excepto
la penúltima que reemplaza Yn por qnqn+1...qm.
N’ se construye a partir de N añadiendo todos los nuevos No Terminales.
Ejemplos:
Sea la GSC G=({S},{a,b,c,d},{S-->ab,ab-->cd},S)
Luego de la Mayusculización tenemos el siguiente conjunto de producciones:
S-->XaXb
XaXb-->XcXd
Xa-->a Xb-->b
Xc-->c Xd-->d
Excepto la producción XaXb-->XcXd todas respetan la forma normal con =,=, su parte
izquierda como A y su parte derecha como .
En la producción XaXb-->XcXd: n=m=2, así reemplazamos esta por:
XaXb-->WXb
WXb -->WXd
WXd -->XcXd
275
Sea la GSC G=({S,B,C},{a,b,c},P,S)
P:
S-->aSBC
S-->abC
CB-->BC
bB-->bb
bC-->bc
cC-->cc
Luego de la Mayusculización tenemos el siguiente conjunto de producciones:
que respetan la forma normal excepto la 3
S-->XaSBC =,=, A=S, =XaSBC
S-->XaXbC =,=, A=S, =XaXbC
CB-->BC no respeta el tipo
XbB-->XbXb =Xb,=, A=B, =Xb
XbC-->XbXc =Xb,=, A=C, =Xc
XcC-->XcXc =Xc,=, A=C, =Xc
Xa-->a
Xb-->b
Xc-->c
276
En efecto, podemos suponer sin pérdida de generalidad que a G ya se le ha aplicado el proceso
de Mayusculización. A partir de P construimos P’ así:
1) Si una producción de P ya tiene el tipo indicado no debemos hacerle ningún cambio y la
copiamos en P’.
2) Si en P está la producción A-->X1...Xm con m>2 se le aplica un proceso de partición tal
como se hizo en la forma normal de Chomsky en gramáticas libres de contexto.
3) Si en P está la producción X1...Xn-->Y1...Ym con n2 y mn (nótese que por la
mayusculización todos los símbolos son No Terminales), se reemplaza por las siguientes
producciones:
X1X2 --> Y1W1
WjXj+2 --> Yj+1Wj+1 j=1,...,n-2
Wn-1 --> Yn...Ym (si esta producción tiene la parte derecha de longitud mayor a 2
se le aplica el proceso de partición de Chomsky)
Todos los Wi son nuevos No Terminales.
N’ se construye a partir de N añadiendo todos los nuevos No Terminales.
Ejemplo:
Sea la GSC G=({S,A,B,C,D,E},{a,b,d,c,e},P,S)
P:
S-->ABCD
S-->ABC
ABC-->DDD
ABCD-->CCACBEE
A-->a B-->b
C-->c D-->d
E-->e
Construimos así la GSC G’=(N’,{a,b,d,c,e},P’,S)
P’:
1)
A-->a
B-->b
C-->c
D-->d
E-->e
2) De S-->ABCD
S-->AZ1
Z1-->BZ2
Z2-->CD
De S-->ABC
S-->AZ3
Z3-->BC
277
3) De ABC-->DDD
AB-->DW1
W1C-->DW2
W2-->D
De ABCD-->CCACBEE
AB-->CV1
V1C-->CV2
V2D-->AV3
V3-->CBEE esta producción se reemplaza por
V3-->CZ4
Z4-->BZ5
Z5-->EE
De manera que después de esta transformación, todas las producciones de P son tales que
la parte izquierda es igual -en longitud- a la parte derecha. Denominaremos j a la longitud de
la parte derecha (o izquierda) de la producción j-ésima, supondremos que existen |P|=k
producciones.
278
4) p1 b R p1
p1 S R p 2
p2 b R p 2
p2 L qf
K={q0,q1,q2,qf,p1,p2} {jqh / j=1,...,k; h=1,...,j} {jph / j=1,...,k; h=1,...,j}
Ejemplo:
Sea la GSC G=({S,B,A},{a},P,S) cuyo conjunto de producciones transformadas (con k=5) es
P:
i) Sb-->BS 1=2
ii) S-->A 2=1
iii) BA-->aA 3=2
iv) Bab-->aaB 4=3
v) A-->a 5=1
1) q0 a a q1 q0 a a p1
q0 S S q1 q0 S S p1
q0 B B q1 q0 B B p1
q0 A A q1 q0 A A p1
q0 b b q1 q0 b b p1
2) q1a R q1 q1 B B p1
1
q2a L q2
q1 S R q1 q1 A A 2p1 q2 S L q2
q1 B R q1 q1 a a 3p1 q2 B L q2
q1 A R q1 q1 a a 4p1 q2 A L q2
q1 b R q1 q1 a a 5p1 q2 b L q2
q1 R q1 q2 L q2
q1 L q2 q2 R q0
279
3) Para i) Sb-->BS 1=2
1
p1 B S 1q1
1
q1 S R 1p2
1
p1 b R 1p1
1
p2 S b q2
280
Construcción de una GSC a partir de un ALL
Sea A un ALL, entonces podemos construir una GSC G tal que L(G)=T(A)-{}.
2) Z --> cZ c(N2)
Z --> Zc c(N2)
Z --> bqf b(N2)
Z --> a)qf a()
Z --> (aqf a()
3) Si q L p es una regla de A
b]p --> b)q b()
4) Si q R p es una regla de A
[bp --> (bq b()
5) Si q a L p es una regla de A
bpa --> baq b()
bpa] --> ba]q b()
[bpa --> [baq b()
[bpa] --> [ba]q b()
(ap --> [aq
6) Si q a R p es una regla de A
abp --> aqb b()
[abp --> [aqb b()
ab]p --> aqb] b()
[ab]p --> [aqb] b()
a)p --> a]q
281
7) Si q a b p es una regla de A
bp --> aq
[bp --> [aq
b]p --> a]q
Las producciones de 9 son necesarias puesto que las producciones de 2 a 8 sólo generan –en
G- cadenas de 2 o más símbolos (que son aceptadas por A).
Ejemplo:
Sea el ALL A=({q0,qf},{a,b}{,},,q0,{qf}) (en este caso =)
:
q0 L qf
q0 R qf
q0 a L q0
q0 a L qf
q0 a R qf
q0 a b qf
Sólo para tener un ejemplo más abarcador este ALL tiene varias cuádruplas que hacen
finalmente lo mismo, debiera ser claro que T(A)={}{aw / w*}
P:
1) S --> Z
S --> X
282
2)
Z --> aZ Z --> Za Z --> aqf Z --> a)qf Z --> (aqf
Z --> bZ Z --> Zb Z --> bqf Z --> b)qf Z --> (bqf
Z --> [aZ Z --> Z[a Z --> [aqf
Z --> [bZ Z --> Z[b Z --> [bqf
Z --> a]Z Z --> Za] Z --> a]qf
Z --> b]Z Z --> Zb] Z --> b]qf
3) De q0 L qf
a]qf --> a)q0
b]qf --> b)q0
4) De q0 R qf
[aqf --> (aq0
[bqf --> (bq0
5) De q0 a L q0
aq0 a --> a aq0
bq0 a --> b aq0
aq0 a] --> a a]q0
bq0 a] --> b a]q0
[aq0 a --> [a aq0
[bq0 a --> [b aq0
[aq0 a] --> [a a]q0
[bq0 a] --> [b a]q0
(aq0 --> [aq0
De q0 a L qf
aqf a --> a aq0
bqf a --> b aq0
aqf a] --> a a]q0
bqf a] --> b a]q0
[aqf a --> [a aq0
[bqf a --> [b aq0
[aqf a] --> [a a]q0
[bqf a] --> [b a]q0
(aqf --> [aq0
6) De q0 a R qf
a aqf --> aq0 a
a bqf --> aq0 b
[a aqf --> [aq0 a
283
[a bqf --> [aq0 b
a a]qf --> aq0 a]
a b]qf --> aq0 b]
[a a]qf --> [aq0 a]
[a b]qf --> [aq0 b]
a)qf --> a]q0
7) De q0 a b qf
bqf --> aq0
[bqf --> [aq0
b]qf --> a]q0
8)
Unión
Los lenguajes sensibles al contexto son cerrados respecto de la operación unión.
Sean G1=(N1,T1,P1,S1) y G2=(N2,T2,P2,S2) dos GSC’s en forma normal tales que L(G1)=L1 y
L(G2)=L2 con (N12 S(N1N2), entonces podemos construir una GSC G tal que
L(G)=L1L2.
La construcción y la demostración son prácticamente las mismas que para GLC’s.
Construimos así la GSC G=(N1N2{S},T1T2,{S-->S1}{S-->S2}P1P2,S).
Nótese que si las GSC’s no están en forma normal la construcción puede dar lugar a cosas
erróneas:
Sea G1=({S1},{a},{S1-->a},S1) y G2=({S2},{a,b,d},{S2-->b,a-->d},S2). Es claro que ambas son
GSC’s, que L(G1)={a} y que L(G2)={b}, siguiendo la construcción indicada tenemos que
G=({S,S1,S2},{a,b,d},{S-->S1,S-->S2,S1-->a,S2-->b,a-->d},S) que genera L(G)={a,b,d} que
evidentemente no es la unión deseada.
284
Concatenación
Los lenguajes sensibles al contexto son cerrados respecto de la operación concatenación.
Sean G1=(N1,T1,P1,S1) y G2=(N2,T2,P2,S2) dos GSC’s tales que L(G1)=L1 y L(G2)=L2 con
(N12 S(N1N2), entonces podemos construir una GSC G tal que L(G)=L2.L1.
Necesitamos más requerimientos sobre G1 y G2 para aplicar la construcción vista en las
GLC’s, pues hacerlo directamente acarrea errores como se muestra a continuación.
Sean las GSC’s G1=({S1},{a},{S1-->a},S1) y G2=({S2},{a,b,d},{S2-->b,aS2-->ad},S2). Nótese
que L(G1)={a} y L(G2)={b}. Siguiendo directamente la construcción mencionada, tenemos
que G=({S,S1,S2},{a,b,d},{S-->S1S2,S1-->a,S2-->b,aS2-->ad},S) que genera L(G)={ab,ad} que
evidentemente no es la concatenación deseada, incluso bajo el hecho de las dos gramáticas
iniciales están en forma normal.
Lo que sucede es que los contextos, que se consideran en la parte izquierda de las
producciones (para aplicarlas), no están siendo diferenciados, es decir, “se mezclan”.
Debemos pues diferenciarlos y una forma que no resta generalidad al enunciado es exigir que
las dos gramáticas iniciales G1 y G2 sean tales que tengan sólo No Terminales en la parte
izquierda de sus producciones, si a ello le sumamos que N1 y N2 son disjuntos entonces la
posibilidad de mezcla desaparece.
Construimos así la GSC G=(N1N2{S},T1T2,{S-->S1S2}P1P2,S).
Ejemplo:
Sean las GSC’s G1=({S1},{a},{S1-->a},S1) y G2=({S2},{a,b,d},{S2-->b,aS2-->ad},S2).
Como G2 no cumple el requerimiento, construimos G’ a partir de G2 tal que L(G’)=L(G2)
como ya se sabe:
G’=({S2,Xa,Xb,Xd},{a,b,d},{S2-->Xb,XaS2-->XaXd,Xa-->a,Xb-->b,Xd-->d},S2)
Finalmente construimos así la GSC G=({S,S1,S2,Xa,Xb,Xd},{a,b,d},P,S)
P:
S-->S1S2
S1-->a
S2-->Xb
XaS2-->XaXd
Xa-->a
Xb-->b
Xd-->d
Estrella de Kleene
Los lenguajes sensibles al contexto son cerrados respecto de la operación Cruz de Kleene.
En el caso de GSC’s hablamos de la cruz de Kleene pues no manjean .
Al igual que en el anterior caso es posible que al aplicar directamente la solución para GLC’s
los contextos, que se consideran en la parte izquierda de las producciones (para aplicarlas), no
se diferencien, es decir, “se mezclen”, como mostramos a continuación incluso si la GSC
inicial tiene sólo No Terminales en la parte izquierda de sus producciones.
Sea la GSC G1=({S1,A},{a,b},{S1-->A,AS1-->Ab,A-->a},S1). Nótese que L(G1)={a}.
285
Siguiendo directamente la construcción mencionada, tenemos que
G=({S,S1,A},{a,b},P,S)
P:
S-->S1S
S-->S1
S1-->A
AS1-->Ab
A-->a
Sea G1=(N1,T1,P1,S1) una GSC que tiene sólo No Terminales en la parte izquierda de sus
producciones tal que L(G1)=L1, con SN1, entonces podemos construir una GSC G tal que
L(G)=L1+ así:
A partir de G1 obtenemos la GSC G2=(N2,T1,P2,S2) que es prácticamente la misma que G1
salvo que los nombres de las No Terminales tienen el subíndice 2 de manera que (N1N2={}
y SN2. Es claro que L(G2)=L1=L(G1).
Ahora, con G1 y G2, construimos G así:
G=(N1N2{S},T1,{S-->S1S2S,S-->S1S2,S-->S1}P1P2,S).
De manera que tendremos derivaciones que comiencen así S=>+S1S2S1S2...S1S2(S1), cada
símbolo S1 (o S2) derivará una cadena de L1, y como N1N2 no hay posibilidad de mezcla.
Ejemplo:
Sea la GSC G1=({S1,A},{a,b},{S1-->A,AS1-->Ab,A-->a},S1).
Construimos así la
GSC G2=({S2,A2},{a,b},{S2-->A2,A2S2-->A2b,A2-->a},S2).
Y así la la GSC G=({S,S1,A,S2,A2},{a,b},P,S)
P:
S-->S1S2S
S-->S1S2
S-->S1
S1-->A
AS1-->Ab
A-->a
S2-->A2
A2S2-->A2b
A2-->a
286
Intersección
Los lenguajes sensibles al contexto son cerrados respecto de la operación intersección.
Sean A1=(K1,11{,},1,q0,{qf}) y A2=(K2,22{,},2,p0,{pf}) dos ALL’s
tales que T(A1)=L1 y T(A2)=L2 con (K12)={} y rh(K1K2), entonces podemos construir
un ALL A tal que T(A)=L1L2.
La idea de la construcción es que el ALL A actúe primero como A1 y si la cadena es aceptada
por este primer ALL luego actúe como A2 con la misma cadena. Como sólo tenemos una cinta
para la cadena de entrada, es usual copiar dicha cadena en una “cinta auxiliar” y si A1 acepta
la entrada, reponer dicha cadena de la cinta auxiliar a la cinta de entrada del ALL A. Ello se
hace de la siguiente ingeniosa manera utilizando la única cinta que tenemos en A:
Cada símbolo de entrada ai en la cinta, se reemplaza por el (nuevo) símbolo ici, por ejemplo si
en la cinta tenemos la entrada aba=a1a2a1, se la reemplaza por 1c12c21c1 (la negrita es sólo para
diferenciar el símbolo del centro). Luego se construye a partir de A1 un conjunto de
cuádruplas que trabajan de manera semejante a 1 pero sobre los superíndices i de los
símbolos icj. He aquí la simulación de dos cintas: los superíndices trabajan como lo símbolos
de la cinta “de arriba” y los subíndices actúan como la “cinta auxiliar de abajo”. Todo lo que
hace A1 se hace en la “cinta de arriba”. Si A1 llega a su estado final, pasamos al estado inicial
de A2 y, o bien trabajamos en la “cinta de abajo” o bien reponemos la entrada original
cambiando cada símbolo icj por aj.
Nótese que además de los símbolos ici necesitamos otros del tipo icj.
287
r3 icj aj r3 i=1,..,n Reponemos la entrada original almacenada
j=1,..,n en la “cinta inferior”
r 3 aj L r 3 j=1,..,n
r3 R p0 Y empezamos el trabajo de A2
Ejemplo:
Sea el ALL A1=({q0,q1,qf},{a,b}{,},1,q0,{qf})
1:
q0a R q1
q1b R q1
q1 L qf
288
Complemento
Immerman y Szelepscényi demostraron en 1988/1987 que los lenguajes sensibles al contexto
son cerrados respecto de la operación complemento.
Dicha demostración se basa más en resultados sobre computabilidad que sobre lenguajes
formales.
Sin ofrecer la demostración podemos indicar algunas cosas sobre ella.
Se sabe que es posible simular más de una cinta de trabajo en un sola cinta en las máquinas de
Turing en general y en los ALL en particular, como muestra el caso de la intersección (donde
el nodeterminismo se nota bien al elegir una de entre varias cuádruplas alternativas).
Immerman utiliza varias cintas para contadores y contenedores de cadenas para probar que si
un lenguaje es aceptado por una máquina de Turing no determinística utilizando un espacio
lineal en función de la entrada entonces también su complemento es aceptado por una
máquina de Turing no determinística. Esto suele anotarse así: NSPACE[s(n)]=co-Space[s(n)].
Dado que Kuroda demostró que LSC=NSPACE[s(n)], es decir para aceptar un lenguaje
sensible al contexto se puede utilizar un ALL que requiera una cantidad de espacio que es
función lineal respecto de la entrada.
El resultado del complemento sigue inmediatamente.
¿Cómo se comporta la solución de Immerman? Dado un ALL A que acepta L se requiere
construir un ALL A’ que acepte cadenas cuando A las rechaza. Cuando todos los cómputos de
A con w en su cinta de entrada fallen en llegar a su estado final y sólo entonces A’ debe
aceptar w.
Immerman descubrió que para que A’ persiga la pista de lo que hace A basta contar las d.i.
Ello es posible pues para la cinta conteniendo w, con |w|=n y |K|=k estados hay un número
finito t = |w|·k·n|w| de d.i.
Podemos limitar el tiempo de corrida de A -con la entrada w- a t, pues cualquier serie de
movimientos de largo mayor a t repetirá alguna d.i. necesariamente.
El número t puede almacenarse en base n por una cadena cuya longitud
≤ log(|w|)+log(k)+|w|+1 = O(|w|). Con lo que la condición sobre el espacio empieza a
satisfacerse.
289
Si r=m entonces acepte w, en otro caso rechace w.
Si A acepta w, A’ encontrará nodeterminísticamente la serie de movimientos hasta llegar a la
d.i. de aceptación y rechazará w. En otro caso, A’ encontrará nodeterminísticamente todas las
m d.i. alcanzables desde I y la última condición del procedimiento hará que acepte w.
290
PROBLEMAS DE DECISIÓN
Presentaremos ahora algunos resultados conocidos para lenguajes sensibles al contexto.
Seguidamente lo que haremos será representar cada una de las GSC’s por una sola cadena en
el alfabeto B={0,1} (aquí pensamos básicamente en la representación del conjunto de
producciones, pero es fácil generalizar ello a la descripción de toda la gramática), para ello
utilizamos los siguientes reemplazos (el “;” está pensado como separador de producciones):
291
a se reemplaza con 0
--> se reemplaza con 01
; se reemplaza con 011
Xi se reemplaza con 01i+2
No todas las cadenas de B* representan GSC’s, pero dada una de estas cadenas hay a lo más
una GSC representada por ella.
Ahora podemos ordenar lexicográficamente todas las cadenas de B* y por tanto ordenar todas
las GSC’s.
Sea Lj el lenguaje generado por la j-ésima GSC de esta ordenación y sea L={aj / ajLj}.
L no es sensible al contexto. En efecto, supongamos que lo sea, es decir hay una GSC que
genera L; por lo tanto dicha GSC debe estar en la ordenación mencionada, digamos que es la
k-ésima GSC de esta ordenación, es decir, L=Lk. Pero entonces resulta que
akL si y sólo si akLk por la forma de L
si y sólo si a L
k
pues Lk=L
Esta contradicción prueba nuestra afirmación.
Se puede decir más aún, L así definido es recursivo (véase el siguiente capítulo). En efecto,
dada la cadena “aj” podemos determinar si está o no en L así: primero ubicamos en la
ordenación la j-ésima GSC, luego dado que esta gramática es recursiva podemos observar si aj
está o no en Lj, si no lo está aj es de L, en otro caso no.
292
CAPÍTULO 17. RELACIONES Y CONVERSIONES ENTRE NIVELES DE LA
JERARQUÍA DE CHOMSKY
Ejemplo:
A partir del siguiente AFN A’=({q1,q2},{a,b},d,q1,{q2})
d:
d(q1,a)={q1,q2}
d(q2,b)={q1,q2}
Construimos así el AP e.f. A=({q1,q2},{a,b},{Z},,q1,Z,{q2})
:
(q1,a,Z)={(q1,Z),(q2,Z)}
(q2,b,Z)={(q1,Z),(q2,Z)}
Mencionemos además que hay lenguajes libres de contexto que no son regulares, por ejemplo
{aibi / i>0}.
Jerarquía de Chomsky
Se conoce como Jerarquía de Chomsky a una categorización por niveles de los lenguajes y sus
gramáticas y autómatas asociados. La más común es la siguiente:
293
L3: Lenguajes tipo 3 o regulares, soportados por los autómatas finitos y las gramáticas
regulares, por ejemplo {ai / i>0}.
L2: Lenguajes tipo 2 o libres (independientes) de contexto, soportados por los autómatas de
pila y las gramáticas libres de contexto, por ejemplo {aibi / i>0}.
L1: Lenguajes tipo 1 o sensibles al contexto, soportados por los autómatas limitados
linealmente y las gramáticas sensibles al contexto, por ejemplo {aibici / i>0}.
L0: Lenguajes tipo 0 o recursivamente enumerables, soportados por las gramáticas tipo 0 y las
máquinas de Turing. Es más usual estudiar estos desde la perspectiva de las máquinas de
Turing y la computabilidad, que se constituyen en un capítulo fundamental de la teoría de la
computación más allá de los lenguajes formales.
La jerarquía mencionada es esta:
L3 L2 L1 L0
Algunas investigaciones han agregado tipos (o familias) de lenguajes entre estas cuatro
clásicas, por ejemplo los lenguajes libres de contexto determinísticos L’ son tales que
L3 L’ L2.
Variantes
Para las gramáticas y –en particular- los autómatas presentados, se han sugerido y estudiado
una cantidad importante de variantes. Por ejemplo controlando el orden en que se utilizan las
producciones como en las gramáticas denominadas atributivas. O bien dando o quitando
flexibilidad a los autómatas ya sea en el manejo de la cinta de entrada o en otros componentes
de los mismos, por ejemplo autómatas de pila con más de una pila, con un sólo símbolo en la
pila (counter pushdown), autómatas finitos que pueden ir a derecha o izquierda en la cinta de
entrada (bidireccionales), y un largo etcétera.
294
Sólo a título de ejemplo daremos una descripción de uno de ellos, invitando al(a la) lector(a) a
indagar en los otros casos:
Ejemplo:
Sea el siguiente AFP A=({q0,q1},{a,b},,Q0,{q1},=0.8)
:
0.7 0.3 0.4 0.6
M(a)= M(b)=
0.6 0.4 0.6 0.4
Q0=[0.5 0.5]
295
F=[0 1] T
0.7 0.3 0.4 0.6 0.4 0.6 0.508 0.492
M(abb)=M(a) X M(b) X M(b)= X X =
0.6 0.4 0.6 0.4 0.6 0.4 0.504 0.496
0.508 0.492 T
pf(abb)=Q0 X M(w) X F=[0.5 0.5] X X [0 1] =0.494
0.504 0.496
Como pf(abb) no es mayor que el punto de corte =0.8, la cadena w no es aceptada.
296
BIBLIOGRAFÍA
Brzozowski Janusz. “Derivatives of regular expressions”. Journal of the ACM. Vol. 11, No. 4,
pp. 481-494. 1964.
Davis, Martin; Sigal Ron; Weyuker Elaine. “Computability, complexity and languages”.
Academic Press. Segunda edición. 1994.
García Pedro et al. “Teoría de autómatas y lenguajes formales”. Alfaomega. Primera edición.
2001.
Ginzburg A. “A procedure for checkin equality of regular expressions”. Journal of the ACM
Vol 14, No. 2, pp. 355-362. 1967.
Kelley Dean. “Teoría de autómatas y lenguajes formales”. Prentice Hall. Primera edición
1995.
Linz Peter. “An Introduction to Formal Languages and Automata”. Jones & Bartlett Learning.
Sexta edición. 2016.
297
ÍNDICE
AFD, 25
AFN, 36
Alfabeto, 1
ALL, 76
Ambigüedad, 59
APe.f., 71
AP, 64
Árboles, 55
Arden, 106, 147
Autómatas de pila, 64
Autómatas finitos determinísticos, 25
Autómatas finitos probabilísticos, 295
Autómatas limitados linealmente, 76
Brzozowski, 96, 141
Cabeza de la parte derecha, 203
Cadena, 1
Cerradura, 161, 246, 274
Clausura reflexiva transitiva, 44
Cociente, 82
Complemento, 167, 253, 289
Concatenación, 164, 248, 185
Cruz de Kleene, 6, 219, 256
Cuasi-gramáticas libres de contexto, 204
CYK, 233
Chomsky, 162
Derivadas, 65
Descripción instantánea, 38, 39, 169
Diferencia, 6, 133
Earley, 141
Ecuaciones, 75
Equivalencia, 145
Estrella, 5
Estrella de Kleene, 168, 250, 285
Expansión, 210
Expresiones regulares, 52
FNCH, 63
FNG, 63
FNK, 276
Forma normal, 63
Ginzburg, 188
GLC, 54
GLC limpia, 62
Glushkov, 134
Gramática libre de contexto, 54
298
Gramática regular lineal derecha, 7
Gramática regular lineal izquierda, 18
Gramáticas LL y LR, 272
Gramáticas regulares, 7
Greibach, 63
GRLD, 7
GRLI, 18
GSC, 241
Immerman, 289
Intersección, 167, 253, 287
Inversa, 2
Jerarquía de Chomsky, 293
Kleene, 82
Kuroda, 276
Lema de bombeo, 87, 203
Lenguaje, 2
Lenguajes sensibles al contexto, 74
Longitud, 2
McNaughton, 133
Minimización, 151
Moore, 188
Myhill-Nerode, 89
No terminales inaccesibles, 61
No terminales inútiles, 61
Ogden, 205
Paso de derivación, 10
Poda, 210
Potencia, 3
Prefijo, 3
Problemas de decisión, 184, 265, 291
Producciones borradoras, 62
Producciones renombradoras, 62
Recursivo por izquierda, 203
Regla de transición, 25
Reinicializable, 120
Símbolo, 1
Subcadena, 4
Sufijo, 4
Suma directa, 188
Thompson, 133
Transiciones vacías, 42
Unión, 161, 246, 284
Yamada, 134
-AFN, 42
-cierre, 42
299