Unione di linguaggi regolari
Siano L1, L2 due linguaggi regolari. Dimostreremo che anche la loro unione L = L1 ∪ L2 è un linguaggio regolare.
Procedimento con un automa deterministico
Idea del procedimento
Abbiamo due linguaggi regolari L1 e L2 e vogliamo dimostrare che la loro unione L1 ∪ L2 è ancora un linguaggio regolare. Poiché L1 e L2 sono regolari, esistono automi a stati finiti A1 e A2 che accettano i linguaggi L1 e L2, cioè L(A1) = L1 e L(A2) = L2. Costruiremo un automa a stati finiti A che accetta il linguaggio L1 ∪ L2, e così dimostreremo che L1 ∪ L2 è regolare.
Come procediamo? Abbiamo gli automi a stati finiti A1 e A2, che accettano i singoli linguaggi. Possiamo dire che la parola w appartiene al linguaggio L1 ∪ L2 se e solo se è accettata da almeno uno degli automi A1 o A2.
L’automa A potrebbe funzionare così: per l’ingresso w simula il calcolo dell’automa A1 sull’ingresso w. Se A1 accetta la parola w, allora la parola w è accettata anche da A. Se A1 rifiuta la parola w, allora A prova a simulare il calcolo di A2 sull’ingresso w. Se A2 accetta la parola w, allora anche A accetta la parola w. Altrimenti la rifiuta.
Ci resta da formalizzare cosa significa che l’automa A «simula» il calcolo di un altro automa.
Formalizzazione
Abbiamo due linguaggi regolari L1 e L2, accettati dagli automi a stati finiti
Costruiamo l’automa a stati finiti A = ⟨Q, Σ, δ, q, F⟩ che accetta il linguaggio L = L1 ∪ L2. Sfruttiamo l’idea di simulare due automi A1, A2. Immaginiamo di avere in ingresso la parola w = w1w2… wn e di simulare contemporaneamente l’esecuzione degli automi A1 e A2 sulla parola w. La configurazione iniziale dell’automa A1 è ⟨q1, w1w2… wn⟩, quella di A2 è ⟨q2, w1w2… wn⟩. In ciascun automa eseguiamo ora un passo di calcolo e arriviamo alle configurazioni ⟨δ1(q1, w1), w2… wn⟩ e ⟨δ2(q2, w1), w2… wn⟩.
Vediamo che queste configurazioni differiscono solo nella prima componente, mentre la seconda – la parte non ancora letta della parola – è sempre la stessa. Durante la simulazione non serve quindi mantenere due configurazioni di due automi: ne basta una della forma ⟨⟨qi, qj⟩, wl… wn⟩, dove qi ∈ Q1 e qj ∈ Q2. In altre parole, l’automa A che stiamo costruendo avrà la configurazione iniziale ⟨⟨q1, q2⟩, w⟩. La prima parte della coppia ⟨q1, q2⟩ rappresenta lo stato in cui si trova al momento l’automa A1 e la seconda componente rappresenta lo stato attuale dell’automa A2.
Possiamo quindi scrivere che l’automa A avrà come insieme degli stati Q = Q1 × Q2. Sarà il prodotto cartesiano degli stati dei due automi precedenti. L’idea è che l’automa A abbia lo stato iniziale ⟨q1, q2⟩ e che, se l’automa A1 con il simbolo w1 passa nello stato qi e l’automa A2 con il simbolo w1 passa nello stato qj, allora l’automa A con il simbolo w1 passa nello stato ⟨qi, qj⟩.
La funzione di transizione δ si scrive così (qui supponiamo di trovarci già negli stati qi e qj):
Restano solo alcuni dettagli. Per l’alfabeto vale Σ= Σ1 ∪ Σ2. Lo stato iniziale è q = ⟨q1, q2⟩. Gli stati finali sono tutte le coppie ⟨qi, qj⟩ tali che qi ∈ F1 oppure qj ∈ F2.
Illustrazione del procedimento
Consideriamo due automi. Il primo è l’automa A1, che accetta tutte le parole (compresa la parola vuota) in cui si alternano zeri e uni, cioè le parole della forma 01, 0101, 010101, …
L’altro automa A2 accetta le parole che contengono almeno uno zero:
L’unione di questi linguaggi è formata dalle parole che contengono uno zero oppure hanno la forma 01, 0101, … Costruiamo ora l’automa a stati finiti A = ⟨Q, Σ, δ, q, F⟩ che accetta proprio questo linguaggio unione. Per prima cosa vediamo come saranno fatti gli stati del nuovo automa A. Il loro insieme sarà il prodotto cartesiano degli stati del primo e del secondo automa:
Questi sono i sei stati dell’automa A che accetta il linguaggio unione L(A1) ∪ L(A2). Nel diagramma sarebbero così:
Non spaventarti se ci sono stati formati da coppie di stati: serve solo a orientarsi meglio in ciò che accade nell’automa. Gli stati potrebbero tranquillamente chiamarsi in modo classico q0, …, q5. Gli stati finali sono quelli che contengono lo stato q0 oppure p1, che sono gli stati finali degli automi originali. Lo stato iniziale è ⟨q0, p0⟩.
Ora dobbiamo trovare tutte le transizioni. Scriviamo una tabella di questo tipo:
e la completiamo a poco a poco. Per prima cosa vediamo dove porta la transizione dallo stato ⟨q0, p0⟩ con l’ingresso 0. Vediamo dove porta la transizione dallo stato q0 con l’ingresso 0 nell’automa A1: porta nello stato q1. Nell’automa A2 la transizione da p0 con lo zero porta nello stato p1. Quindi nella tabella scriviamo ⟨q1, p1⟩:
Con l’ingresso 1 otteniamo: per l’automa A1 abbiamo δ1(q0, 1) = q2 e per l’automa A2 abbiamo δ2(p0, 1) = p0. Otteniamo così lo stato ⟨q2, p0⟩.
Completiamo il resto della tabella:
E in base a questa tabella non resta che disegnare il resto del diagramma.
Possiamo verificare che l’automa funziona come deve. Proviamo a dargli in ingresso la parola 0100. L’automa attraversa in successione gli stati
Poiché lo stato ⟨q2, p1⟩ è finale, l’automa A accetta la parola 0100. Come andrebbe se dessimo in ingresso la parola 0100 agli automi A1 e A2? L’automa A1 attraverserebbe in successione questi stati:
L’automa è finito nello stato q2, che non è finale, quindi A1 non accetterebbe questa parola. E l’automa A2?
Lo stato p1 è finale, quindi l’automa A2 accetterebbe la parola 0100. Osserva che gli automi A1 e A2 sono finiti negli stati q2 e p1, in accordo con il fatto che l’automa A è finito nello stato ⟨q2, p1⟩.
Procedimento con un automa non deterministico
Esempio
Il fatto che l’insieme dei linguaggi regolari sia chiuso rispetto all’unione si può dimostrare anche costruendo un automa non deterministico, che sarà molto più semplice.
Abbiamo quindi due linguaggi regolari L1, L2 e vogliamo dimostrare che la loro unione L = L1 ∪ L2 è anch’essa un linguaggio regolare. Poiché L1, L2 sono linguaggi regolari, devono esistere automi A1, A2 che accettano questi linguaggi. Cioè vale L(A1) = L1 e L(A2) = L2. Con questi automi costruiamo l’automa A che accetta il linguaggio L, cioè L(A) = L.
Supponiamo che gli automi a stati finiti A1 e A2 siano fatti così:
e
L’automa che accetta l’unione dei due linguaggi si costruisce creando un nuovo stato iniziale e facendo partire da questo stato due ε-transizioni verso gli stati iniziali originali. Tutto qui. L’automa sarebbe così:
Formalizzazione
Abbiamo due automi A1 = ⟨Q1, Σ, δ1, q1, F1⟩ e A2 = ⟨Q2, Σ, δ2, q2, F2⟩. Costruiamo l’automa A = ⟨Q, Σ, δ, q0, F⟩ che accetta l’unione dei linguaggi accettati dagli automi precedenti, cioè L(A) = L(A1) ∪ L(A2). Inoltre vale:
- Q = Q1 ∪ Q2 ∪ {q0}
- F = F1 ∪ F2
E la funzione di transizione δ si definisce così:
Fonti
Capitoli: Chiusura dei linguaggi regolari, Unione di linguaggi regolari, Intersezione di linguaggi regolari, Differenza di linguaggi regolari, Complemento di un linguaggio regolare, Concatenazione di linguaggi regolari, Chiusura di Kleene di un linguaggio regolare