✖

União de linguagens regulares

Considere duas linguagens regulares L1, L2. Vamos demonstrar que a união delas, L = L1 ∪ L2, também é uma linguagem regular.

Procedimento com um autômato determinístico

Ideia do procedimento

Temos duas linguagens regulares L1 e L2 e queremos demonstrar que a união delas, L1 ∪ L2, é de novo uma linguagem regular. Como L1 e L2 são linguagens regulares, existem autômatos finitos A1 e A2 que aceitam as linguagens L1 e L2, ou seja, valem L(A1) = L1 e L(A2) = L2. Nós construiremos um autômato finito A que aceitará a linguagem L1 ∪ L2, e com isso demonstraremos que a linguagem L1 ∪ L2 é regular.

Como faremos isso? Temos à mão os autômatos finitos A1 e A2, que aceitam cada uma das linguagens. Podemos dizer que a palavra w pertence à linguagem L1 ∪ L2 se, e somente se, pelo menos um dos autômatos A1 ou A2 a aceita.

O autômato A poderia funcionar assim: para a entrada w, ele vai simular a computação do autômato A1 para a entrada w. Se A1 aceitar a palavra w, então A também aceita a palavra w. Se A1 rejeitar a palavra w, então A ainda tenta simular a computação de A2 para a entrada w. Se A2 aceitar a palavra w, então A também aceita a palavra w. Caso contrário, rejeita.

Resta-nos formalizar o que significa que o autômato A “simula” a computação de outro autômato.

Formalização

Temos duas linguagens regulares L1 e L2, que são aceitas pelos autômatos finitos

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

Construímos o autômato finito A = ⟨Q, Σ, δ, q, F⟩, que aceitará a linguagem L = L1 ∪ L2. Vamos usar a ideia de simular os dois autômatos A1, A2. Imaginemos, então, que temos na entrada a palavra w = w1w2… wn e que agora vamos simular ao mesmo tempo o andamento dos autômatos A1 e A2 para a palavra w. A configuração inicial do autômato A1 é ⟨q1, w1w2… wn⟩, e a configuração inicial de A2 é ⟨q2, w1w2… wn⟩. Em cada autômato fazemos agora um passo de computação, e com isso chegamos às configurações ⟨δ1(q1, w1), w2… wn⟩ e ⟨δ2(q2, w1), w2… wn⟩.

Vemos que essas configurações diferem apenas na primeira componente; a segunda — a parte não lida da palavra — é sempre a mesma. Durante a simulação, portanto, não precisamos manter duas configurações de dois autômatos, basta-nos uma configuração da forma ⟨⟨qi, qj⟩, wl… wn⟩, em que qi ∈ Q1 e qj ∈ Q2. Em outras palavras, o nosso autômato A, que estamos construindo, terá a configuração inicial ⟨⟨q1, q2⟩, w⟩. A primeira parte do par ⟨q1, q2⟩ representa o estado em que o autômato A1 se encontra no momento, e a segunda componente representa o estado atual do autômato A2.

Podemos escrever, assim, que o autômato A, que estamos construindo, terá o conjunto de estados igual a Q = Q1 × Q2. Será o produto cartesiano dos estados dos dois autômatos anteriores. A ideia seguinte é que o autômato A terá o estado inicial ⟨q1, q2⟩ e, se o autômato A1 passar com o símbolo w1 para o estado qi e o autômato A2 passar com o símbolo w1 para o estado qj, então o autômato A passará com o símbolo w1 para o estado ⟨qi, qj⟩.

Escrevemos a função de transição δ assim (aqui já supomos que estamos no momento nos estados qi e qj):

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

Resta resolver apenas pequenos detalhes. Para o alfabeto vale Σ= Σ1 ∪ Σ2. O estado inicial é igual a q = ⟨q1, q2⟩. E os estados finais são todos os pares ⟨qi, qj⟩ tais que qi ∈ F1 ou qj ∈ F2.

Ilustração do procedimento

Considere dois autômatos. O primeiro é o autômato A1, que aceita todas as palavras (incluindo a palavra vazia) em que se alternam zeros e uns, isto é, palavras da forma 01, 0101, 010101, …

O outro autômato, A2, aceita as palavras que contêm pelo menos um zero:

A união dessas linguagens é formada pelas palavras que contêm um zero ou são da forma 01, 0101, … Agora construímos o autômato finito A = ⟨Q, Σ, δ, q, F⟩, que aceitará exatamente essa linguagem união. Primeiro vamos mostrar como serão os estados desse novo autômato A. Será o produto cartesiano dos estados do primeiro e do segundo autômato:

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

Assim são os seis estados do autômato A, que aceita a linguagem união L(A1) ∪ L(A2). No diagrama ficariam assim:

Não se assuste por termos estados compostos de pares de estados — isso serve apenas para nos orientarmos melhor sobre o que de fato acontece no autômato. Os estados poderiam muito bem se chamar, de maneira usual, q0, …, q5. Os estados finais são aqueles que contêm o estado q0 ou p1, que são os estados finais dos autômatos originais. O estado inicial é ⟨q0, p0⟩.

Agora precisamos encontrar todas as transições. Escrevemos uma tabela assim:

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

E vamos completando a tabela aos poucos. Primeiro descobrimos para onde levará a transição do estado ⟨q0, p0⟩ com a entrada 0. Descobrimos para onde vai a transição do estado q0 com a entrada 0 no autômato A1: ela vai para o estado q1. No autômato A2, a transição de p0 com zero vai para o estado p1. Então escrevemos na tabela ⟨q1, p1⟩:

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

Com a entrada 1 obtemos: para o autômato A1 temos δ1(q0, 1) = q2 e para o autômato A2 temos δ2(p0, 1) = p0. Obtemos, assim, o estado ⟨q2, p0⟩.

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

Completamos o resto da tabela:

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⟩

E, de acordo com essa tabela, só falta desenhar o resto do diagrama.

Podemos testar se o autômato funciona como deve. Vamos tentar aceitar a palavra 0100. O autômato percorrerá, sucessivamente, os estados

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

Como o estado ⟨q2, p1⟩ é um estado final, o autômato A aceita a palavra 0100. Como seria se tentássemos aceitar a palavra 0100 com os autômatos A1 e A2? O autômato A1 percorreria, sucessivamente, estes estados:

q0,q1,q0,q1,q2

O autômato terminou no estado q2, que não é final, então o autômato A1 não aceitaria essa palavra. E o autômato A2?

p0,p1,p1,p1,p1

O estado p1 é final, então o autômato A2 aceitaria a palavra 0100. Observe que os autômatos A1 e A2 terminaram nos estados q2 e p1, o que está de acordo com o fato de o autômato A ter terminado no estado ⟨q2, p1⟩.

Procedimento com um autômato não determinístico

Exemplo

Podemos demonstrar que o conjunto das linguagens regulares é fechado sob a união também construindo um autômato não determinístico, que será muito mais simples.

Temos, assim, duas linguagens regulares L1, L2 e queremos demonstrar que a união delas, L = L1 ∪ L2, também é uma linguagem regular. Como L1, L2 são linguagens regulares, devem existir autômatos A1, A2 que aceitam essas linguagens. Ou seja, valem L(A1) = L1 e L(A2) = L2. Com esses autômatos construímos o autômato A, que aceitará a linguagem L, isto é, L(A) = L.

Suponha que os autômatos finitos A1 e A2 sejam assim:

e

Construiríamos o autômato que aceitaria a união das duas linguagens criando um novo estado inicial e levando, desse estado, duas transições ε para os estados iniciais originais. Só isso. O autômato ficaria assim:

Formalização

Temos dois autômatos A1 = ⟨Q1, Σ, δ1, q1, F1⟩ e A2 = ⟨Q2, Σ, δ2, q2, F2⟩. Construímos o autômato A = ⟨Q, Σ, δ, q0, F⟩, que aceitará a união das linguagens aceitas pelos autômatos anteriores, isto é, L(A) = L(A1) ∪ L(A2). Nesse caso, valem:

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

E definimos a função de transição δ assim:

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

Fontes

Capítulos: Fechamento das linguagens regulares, União de linguagens regulares, Interseção de linguagens regulares, Diferença de linguagens regulares, Complemento de uma linguagem regular, Concatenação de linguagens regulares, Fecho de uma linguagem regular