✖

Unión de lenguajes regulares

Tomemos dos lenguajes regulares L1, L2. Demostraremos que su unión L = L1 ∪ L2 es también un lenguaje regular.

Procedimiento con un autómata determinista

Idea del procedimiento

Tenemos dos lenguajes regulares L1 y L2 y queremos demostrar que su unión L1 ∪ L2 es de nuevo un lenguaje regular. Como L1 y L2 son lenguajes regulares, existen autómatas finitos A1 y A2 que aceptan los lenguajes L1 y L2, es decir, se cumple L(A1) = L1 y L(A2) = L2. A continuación construiremos un autómata finito A que aceptará el lenguaje L1 ∪ L2, con lo que demostraremos que el lenguaje L1 ∪ L2 es regular.

¿Cómo lo hacemos? Disponemos de los autómatas finitos A1 y A2, que aceptan cada uno de los lenguajes. Podemos decir que la palabra w pertenece al lenguaje L1 ∪ L2 si y solo si la acepta al menos uno de los autómatas A1 o A2.

El autómata A podría funcionar así: para la entrada w, simulará el cómputo del autómata A1 para la entrada w. Si A1 acepta la palabra w, también la aceptará A. Si A1 rechaza la palabra w, A intentará todavía simular el cómputo de A2 para la entrada w. Si A2 acepta la palabra w, también A la aceptará. En caso contrario, la rechazará.

Nos queda formalizar qué significa que el autómata A «simula» el cómputo de otro autómata.

Formalización

Tenemos dos lenguajes regulares L1 y L2, que son aceptados por los autómatas finitos

A1=⟨Q1,Σ1,δ1,q1,F1⟩A2=⟨Q2,Σ2,δ2,q2,F2⟩.

Construimos un autómata finito A = ⟨Q, Σ, δ, q, F⟩ que aceptará el lenguaje L = L1 ∪ L2. Aprovechamos la idea de simular dos autómatas A1, A2. Imaginemos que en la entrada tenemos la palabra w = w1w2… wn y que vamos a simular a la vez el funcionamiento de los autómatas A1 y A2 para la palabra w. La configuración inicial del autómata A1 es ⟨q1, w1w2… wn⟩ y la configuración inicial de A2 es ⟨q2, w1w2… wn⟩. En cada autómata realizamos ahora un paso de cómputo, con lo que llegamos a las configuraciones ⟨δ1(q1, w1), w2… wn⟩ y ⟨δ2(q2, w1), w2… wn⟩.

Vemos que estas configuraciones se diferencian solo en la primera componente; la segunda —la parte aún no leída de la palabra— es siempre la misma. Durante la simulación no necesitamos, por tanto, mantener dos configuraciones de dos autómatas, sino que nos basta una configuración de la forma ⟨⟨qi, qj⟩, wl… wn⟩, donde qi ∈ Q1 y qj ∈ Q2. Dicho de otro modo, nuestro autómata A tendrá la configuración inicial ⟨⟨q1, q2⟩, w⟩. La primera parte del par ⟨q1, q2⟩ representa el estado en el que se encuentra en ese momento el autómata A1 y la segunda componente representa el estado actual del autómata A2.

Podemos escribir, pues, que el autómata A que construimos tendrá un conjunto de estados igual a Q = Q1 × Q2. Será el producto cartesiano de los estados de los dos autómatas anteriores. La idea siguiente es que el autómata A tendrá el estado inicial ⟨q1, q2⟩ y que, si el autómata A1 pasa con el símbolo w1 al estado qi y el autómata A2 pasa con el símbolo w1 al estado qj, el autómata A pasará con el símbolo w1 al estado ⟨qi, qj⟩.

La función de transición δ la escribimos así (aquí ya suponemos que nos encontramos en los estados qi y qj):

δ(⟨qi,qj⟩,w)=⟨δ1(qi,w),δ2(qj,w)⟩

Solo nos quedan unos detalles. Para el alfabeto se cumple Σ= Σ1 ∪ Σ2. El estado inicial es q = ⟨q1, q2⟩. Y los estados finales son todos los pares ⟨qi, qj⟩ tales que qi ∈ F1 o qj ∈ F2.

Ilustración del procedimiento

Tomemos dos autómatas. El primero es el autómata A1, que acepta todas las palabras (incluida la palabra vacía) en las que se alternan ceros y unos, es decir, las palabras de la forma 01, 0101, 010101, …

El otro autómata, A2, acepta las palabras que contienen al menos un cero:

La unión de estos lenguajes está formada por las palabras que contienen un cero o que son de la forma 01, 0101, … Ahora construimos el autómata finito A = ⟨Q, Σ, δ, q, F⟩ que aceptará precisamente este lenguaje unión. Primero mostraremos cómo serán los estados de este nuevo autómata A. Será el producto cartesiano de los estados del primer y del segundo autómata:

Q=Q1×Q2={⟨q0,p0⟩,⟨q0,p1⟩,⟨q1,p0⟩,⟨q1,p1⟩,⟨q2,p0⟩,⟨q2,p1⟩}

Así son los seis estados del autómata A, que acepta el lenguaje unión L(A1) ∪ L(A2). En el diagrama tendrían este aspecto:

No te asustes al ver que hay estados formados por pares de estados: sirve solo para orientarnos mejor en lo que ocurre en el autómata. Los estados podrían llamarse tranquilamente, como siempre, q0, …, q5. Los estados finales son los que contienen el estado q0 o el estado p1, que son los estados finales de los autómatas originales. El estado inicial es ⟨q0, p0⟩.

Ahora debemos hallar todas las transiciones. Escribimos una tabla como esta:

01⟨q0,p0⟩⟨q0,p1⟩⟨q1,p0⟩⟨q1,p1⟩⟨q2,p0⟩⟨q2,p1⟩

Y la iremos completando poco a poco. Primero averiguamos adónde llevará la transición desde el estado ⟨q0, p0⟩ con la entrada 0. Vemos adónde lleva la transición desde el estado q0 con la entrada 0 en el autómata A1: lleva al estado q1. En el autómata A2, la transición desde p0 con cero lleva al estado p1. Así que en la tabla escribimos ⟨q1, p1⟩:

01⟨q0,p0⟩⟨q1,p1⟩⟨q0,p1⟩⟨q1,p0⟩⟨q1,p1⟩⟨q2,p0⟩⟨q2,p1⟩

Con la entrada 1 obtenemos: para el autómata A1 tenemos δ1(q0, 1) = q2 y para el autómata A2 tenemos δ2(p0, 1) = p0. Obtenemos así el estado ⟨q2, p0⟩.

01⟨q0,p0⟩⟨q1,p1⟩⟨q2,p0⟩⟨q0,p1⟩⟨q1,p0⟩⟨q1,p1⟩⟨q2,p0⟩⟨q2,p1⟩

Completamos el resto de la tabla:

01⟨q0,p0⟩⟨q1,p1⟩⟨q2,p0⟩⟨q0,p1⟩⟨q1,p1⟩⟨q2,p1⟩⟨q1,p0⟩⟨q2,p1⟩⟨q0,p0⟩⟨q1,p1⟩⟨q2,p1⟩⟨q0,p1⟩⟨q2,p0⟩⟨q2,p1⟩⟨q2,p0⟩⟨q2,p1⟩⟨q2,p1⟩⟨q2,p1⟩

Y a partir de esta tabla solo nos queda dibujar el resto del diagrama.

Podemos comprobar que el autómata funciona como debe. Intentemos aceptar la palabra 0100. El autómata pasa sucesivamente por los estados

⟨q0,p0⟩,⟨q1,p1⟩,⟨q0,p1⟩,⟨q1,p1⟩,⟨q2,p1⟩

Como el estado ⟨q2, p1⟩ es final, el autómata A acepta la palabra 0100. ¿Qué ocurriría si intentáramos aceptar la palabra 0100 con los autómatas A1 y A2? El autómata A1 pasaría sucesivamente por estos estados:

q0,q1,q0,q1,q2

El autómata terminó en el estado q2, que no es final, así que el autómata A1 no aceptaría esta palabra. ¿Y el autómata A2?

p0,p1,p1,p1,p1

El estado p1 es final, así que el autómata A2 sí aceptaría la palabra 0100. Fíjate en que los autómatas A1 y A2 terminaron en los estados q2 y p1, lo que concuerda con que el autómata A terminara en el estado ⟨q2, p1⟩.

Procedimiento con un autómata no determinista

Ejemplo

Que el conjunto de los lenguajes regulares es cerrado respecto de la unión podemos demostrarlo también construyendo un autómata no determinista, que será mucho más sencillo.

Tenemos dos lenguajes regulares L1, L2 y queremos demostrar que su unión L = L1 ∪ L2 es también un lenguaje regular. Como L1, L2 son lenguajes regulares, deben existir autómatas A1, A2 que acepten estos lenguajes, es decir, se cumple que L(A1) = L1 y L(A2) = L2. Con estos autómatas construiremos un autómata A que aceptará el lenguaje L, es decir, L(A) = L.

Supongamos que los autómatas finitos A1 y A2 tienen este aspecto:

y

El autómata que aceptara la unión de ambos lenguajes lo construiríamos creando un nuevo estado inicial y trazando desde él dos transiciones ε hacia los estados iniciales originales. Eso es todo. El autómata tendría este aspecto:

Formalización

Tenemos dos autómatas A1 = ⟨Q1, Σ, δ1, q1, F1⟩ y A2 = ⟨Q2, Σ, δ2, q2, F2⟩. Construimos un autómata A = ⟨Q, Σ, δ, q0, F⟩ que aceptará la unión de los lenguajes aceptados por los autómatas anteriores, es decir, L(A) = L(A1) ∪ L(A2). Se cumple que:

  • Q = Q1 ∪ Q2 ∪ {q0}
  • F = F1 ∪ F2

Y la función de transición δ la definimos así:

δ(q,a)={δ1(q,a)siq∈Q1δ2(q,a)siq∈Q2{q1,q2}siq=q0∧a=ε∅siq=q0∧a≠ε

Fuentes

Capítulos: Propiedades de cierre de los lenguajes regulares, Unión de lenguajes regulares, Intersección de lenguajes regulares, Diferencia de lenguajes regulares, Complemento de un lenguaje regular, Concatenación de lenguajes regulares, Clausura de un lenguaje regular