✖

Omvandling av automat till reguljärt uttryck

Vi ska se hur man omvandlar vilken som helst ändlig automat till ett reguljärt uttryck.

Beskrivning av algoritmen

Vi utgår från någon NFA A. Först gör vi om den till en GNFA. I den andra fasen tar vi bort ett tillstånd i varje steg, ändrar övergångsfunktionen på rätt sätt och upprepar tills det bara finns två tillstånd kvar, starttillståndet och sluttillståndet. Mellan dem går en båge som har ett reguljärt uttryck som etikett, och det uttrycket är resultatet av hela algoritmen. Hela metoden går alltså främst ut på att ta bort ett tillstånd och sedan rätta automaten så att vi får en ekvivalent automat.

Eliminering av ett tillstånd

Hur man tar bort ett tillstånd kan vi visa med ett enkelt exempel. Anta att en del av vår automat ser ut så här:

där Ri är några reguljära uttryck. Hur skulle automaten se ut om vi tog bort tillståndet qr? Vi kan tänka oss att vi befinner oss i tillståndet qi och frågar oss vilka ord vi kan generera på den här sträckan. Om vi går direkt från qi till qj är det alla ord som motsvarar det reguljära uttrycket R4.

Om vi i stället går till tillståndet qr kan vi generera ord av formen R1. I tillståndet qr kan vi dessutom gå runt i en loop med uttrycket R2, så vi kan generera ord av formen R1∘(R2∗). Eftersom vi sedan också kan ta oss från qr till qj lägger vi till det reguljära uttrycket R3. Totalt kan vi alltså på den här vägen få ord av formen R1∘(R2∗)∘R3.

Nu vet vi att den här delen av automaten kan ge ord av formen R4 eller av formen R1∘(R2∗)∘R3. Det kan vi förstås skriva som ett reguljärt uttryck: (R4)|(R1∘(R2∗)∘R3).

Nu kan vi enkelt ta bort tillståndet qr och bara behålla de två tillstånden qi och qj, och i stället för R4 skriver vi det uttryck vi just räknade ut:

Den här proceduren utför vi för varje båge från varje tillstånd qi till något tillstånd qj, också för loopar, dvs. även när qi = qj.

Efter att ha tagit bort ett tillstånd får vi en ekvivalent automat, alltså en automat som känner igen samma språk.

Hela algoritmen

Vi utgår från en NFA A = ⟨Q, Σ, δ, q0, F⟩.

  1. Vi omvandlar NFA:n A till en GNFA Z = ⟨Q′, Σ, δ′, q0′, qf′⟩. Fortsättningsvis betecknar vi antalet tillstånd i Z med bokstaven k.
  2. Om k = 2 avslutas algoritmen, och på bågen mellan starttillståndet och sluttillståndet står det resulterande reguljära uttrycket.
  3. Om k>2 väljer vi ett godtyckligt tillstånd qr som skiljer sig från start- och sluttillståndet, dvs. qr ≠ q0′ och qr ≠ qf′. Därefter skapar vi en ny GNFA Z′ = ⟨Q′′, Σ, δ′′,q0′,qf′⟩ som uppfyller att Q′′=Q′∖{qr} och för alla qi ∈ Q′′ ∖ {qf′} och alla qj ∈ Q′′ ∖ {q0′} låt δ′′(qi,qj)=(R4)|(R1(R2∗)R3), där R1 = δ′(qi,qr), R2 = δ′(qr,qr), R3 = δ′(qr, qj), R4 = δ′(qi, qj). Fortsätt sedan med steg 2.

Exempel

Vi har den här ändliga automaten:

Först omvandlar vi den till en GNFA (de onödiga ∅-övergångarna ritar vi inte ut):

Nu tillämpar vi den andra delen av algoritmen och tar bort någon nod. Vi börjar med noden q2. Vi tar bort noden q2 och lägger till en övergång från tillståndet q1 till tillståndet qf. Den märker vi b(a|b)∗, eftersom vi från noden q1 kommer till tillståndet q2 för ord av formen b, sedan kan vi gå runt i en loop med a|b, vilket ger (a|b)∗, och till sist tar vi oss med epsilonregeln till qf. Det gäller att b(a|b)∗ϵ = b(a|b)∗. Vi får automaten:

Nu återstår att ta bort det sista tillståndet, q1. Vi lägger till en båge från tillståndet qs till tillståndet qf. Hur märker vi den? Till tillståndet q1 kommer vi via epsilonregeln, och den kan vi direkt utelämna. Sedan kan vi gå runt i en loop med a, så vi får det reguljära uttrycket a∗. Och till sist kommer vi via bågen till qf, så vi konkatenerar också uttrycket med b(a|b)∗. Bågen märker vi alltså med det reguljära uttrycket a∗ b(a|b)∗.

Automaten har nu bara två tillstånd, så algoritmen avslutas. På bågen står det resulterande reguljära uttrycket.

Källor

Kapitel: Reguljära uttryck, Omvandling av reguljärt uttryck till automat, Generaliserad icke-deterministisk ändlig automat, Omvandling av automat till reguljärt uttryck