Ciele
- Zopakovať si tvorbu regulárnych výrazov na základe slovnej špecifikácie.
- Definovať deterministický konečnostavovový automat (DKA) ako ekvivalentný spôsob určenia regulárneho jazyka.
- Konštruovať DKA na základe zadaného regulárneho výrazu.
- Implementovať DKA pre daný regulárny výraz vo vyššom programovacom jazyku (tvorba primitívneho jazykového procesora).
Úvod
Cieľom dnešného cvičenia je opakovanie a prehĺbenie teórie regulárnych výrazov a pochopenie priameho odvodenia deterministického konečnostavového automatu z regulárneho výrazu (pomocou metódy vytvárania prechodových diagramov). Ďalším cieľom je pochopenie dodanej implementácie konečnostavového akceptora a možnosť implementácie ďalšieho akceptora.
Postup
Krok 1
Regulárne výrazy predstavujú prvú z pokročilých metód špecifikácie jazyka (konkrétne tzv. regulárneho jazyka), ktorú sme si predstavili na predchádzajúcom cvičení. Zopakujte si teóriu regulárnych výrazov. Samotný princíp určenia jazyka pomocou regulárneho výrazu spočíva v špecifikácii vzoru, ktorý splňajú všetky slová (reťazce) tohto jazyka, ktoré preto možno označiť za konkrétne inštancie tohto vzoru. Ďalej vieme, že regulárne výrazy je možné zobraziť aj graficky pomocou prechodových diagramov. Princíp zostrojenia takýchto diagramov bol vysvetlený taktiež na predchádzajúcom cvičení.
Prostrednícvom nasledujúceho príkladu si teraz zopakujeme tvorbu regulárneho výrazu na základe slovnej špecifikácie ním identifikovaného jazyka a následne pristúpime ku konštrukcii jeho prechodového diagramu.
Úloha 1.1
Skonštruujte regulárny výraz a jemu zodpovedajúci prechodový diagram pre reťazce nad abecedou $A=\{x, y, z\}$, v ktorých bezprostredne po každom výskyte prvku $y$ nasleduje počet znakov $x$ rovný kladnému násobku čísla 2.
Krok 2
Ďalším z pokročilých spôsobov špecifikácie jazyka je takzvaný akceptačný spôsob využitím automatu. Automat predstavuje v teórii informatiky bežne využívaný matematický model, ktorý na vstupe prijma reťazec zložený z terminálnych symbolov. Ten spracuje a v konečnom čase (po konečnom počte operácií) rozhodne, či daný reťazec patrí do takto určeného jazyka alebo nie (hovoríme, že automat slovo akceptuje resp. neakceptuje).

Schému konečnostavového automatu môžeme vidieť na Obr. 1. Tento model sa skladá zo vstupnej pásky a konečnostavovej riadiacej jednotky.Na vstupnej páske je zapísané slovo, o ktorom má automat rozhodnúť, či patrí do jazyka. Konečnostavová riadiaca jednotka sa vždy nachádza v určitom stave a vidí jeden aktuálny vstupný symbol na páske. Konečný automat pracuje diskrétne po jednotlivých krokoch. V každom kroku prečíta aktuálny symbol zo vstupnej pásky, presunie čítaciu hlavu na nasledujúci symbol a prejde do nového stavu. Nový stav sa určí na základe pôvodného stavu a prečítaného vstupného symbolu. Na začiatku výpočtu je čítacia hlava nastavená na prvý symbol slova a konečnostavová riadiaca jednotka sa nachádza v tzv.počiatočnom stave. Výpočet sa skončí, keď sa spracuje celé vstupné slovo alebo sa automat zasekne. Automat slovo akceptuje, ak sa mu podarí spracovať celé vstupné slovo, pričom skončí v tzv. akceptujúcom stave.
Uvedené skutočnosti teraz formalizujeme následovne.
Deterministický konečnostavový automat (DKA) je usporiadaná pätica $$ M = (Q, T, \delta, q_0, F), $$ kde:
- $ Q $ je konečná množina stavov automatu.
- $ T $ je konečná množina prípustných vstupných symbolov (alebo vstupná abeceda) automatu.
- $ \delta $ je prechodová funkcia automatu, $ \delta: Q \times T \rightharpoonup Q $.
- $ q_0 $ je počiatočný alebo iniciálny stav automatu, $ q_0 \in Q $.
- $ F $ je množina akceptujúcich (alebo koncových) stavov automatu, $F \subseteq Q $.
Upozornenie
Prechodová funkcia $\delta$ je parciálna (čiastočne definovaná) funkcia, čo je v rámci jej špecifikácie vyjadrené využitím symbolu "$\rightharpoonup$" namiesto symbolu "$\to$" vyhradeného pre totálne funkcie. Znamená to, že funkcia $\delta$ nemusí byť definovaná pre všetky prvky z jej domény teda množiny $Q\times T$.
Konfigurácia konečného automatu $M=(Q, T, \delta, q_0, F)$ je usporiadaná dvojica $(q, w) \in Q \times T^* $ kde $q$ je momentálny stav automatu $M$ a $w$ je ešte nespracovaná časť vstupu.
- Začiatočná konfigurácia automatu $M$ je konfigurácia $ (q_0, w) $, kde $w$ je celý vstupný reťazec.
- Koncová (alebo akceptujúca) konfigurácia automatu $M$ je konfigurácia $ (q, \varepsilon) $ kde $ q \in F $.
Poznámka
Všimnite si rozdiel medzi konfiguráciou ktorá je prvkom množiny $Q\times T^*$ a argumentom prechodovej funkcie $\delta$, ktorý spadá do množiny $Q\times T$.
Na množine konfigurácií $Q \times T^* $ definujeme binárnu reláciu prechodu (alebo krok výpočtu) DKA $\vdash\;\subseteq (Q \times T^*)^2$ následovne: Nech $q, p \in Q, w \in T^*, x \in T$. Potom $$ (q, xw) \vdash (p, w) \quad \textrm{vtedy a len vtedy, ak} \quad \delta(q, x) = p. $$
Postupnosť (sekvencia) konfigurácií $ (q_0, w_0), (q_1, w_1), \ldots, (q_k, w_k) $, pre $ k \in \mathbb{N}$ takých, že $$ (q_0, w_0) \vdash (q_1, w_1) \vdash \dots \vdash (q_k, w_k), $$ sa nazýva výpočet DKA $M$ z $ (q_0, w_0) \to (q_k, w_k) $ a vyjadrovať ho budeme v tvare $$ (q_0, w_0) \vdash^k (q_k, w_k). $$
Poznámka
Číslo $k$ predstavuje počet krokov výpočtu.
-
tranzitívnym uzáverom relácie krok výpočtu nazývame reláciu $ \vdash^+ $ definovanú na množine jeho konfigurácii následovne:
$ (q,w_1) \vdash^+ (p,w_2) $ práve vtedy, keď existuje $ n \geq 1$ také, že $(q,w_1) \vdash^n (p,w_2) $. -
reflexívnym a tranzitívnym uzáverom relácie krok výpočtu nazývame reláciu $ \vdash^* $ definovanú na množine jeho konfigurácii následovne:
$ (q,w_1) \vdash^* (p,w_2) $ práve vtedy, keď existuje $ n \geq 0$ také, že $(q,w_1) \vdash^n (p,w_2) $.
Slovo $w$ je teda akceptované DKA $M$, ak existuje taký výpočet, že prvá konfigurácia tohto výpočtu je začiatočná konfigurácia s kontrolovaným slovom $w$ a posledná konfigurácia je koncová akceptujúca konfigurácia, teda $$(q_0,w) \vdash^{*} (q,\varepsilon)\text{, kde }q\in F.$$
Jazyk $L(M)$ rozpoznávaný (akceptovaný) konečným automatom $M$ je množina: $$ L(M) = \{ w \mid (q_0, w) \vdash^* (q, \varepsilon) \land w \in T^* \land q \in F \} $$
Krok 3
Konečnostavové automaty sa bežne v teórii informatiky vytvárajú prostredníctvom zostavenia prechodových tabuliek (ako je tomu v zbierke v kapitole 3.2). Takto vytvorené automaty sú nedeterministické. Nedeterministické automaty sú také, kde pri niektorom vstupe $x$ je definovaná prechodová funkcia nie do jediného možného stavu $q$, ale do množiny možných stavov $\{q_1, q_2, \ldots, q_n\}$. O nedeterministických automatoch si povieme viac v nasledujúcom cvičení.
Na vytvorenie deterministického automatu sa využíva metóda nazývaná determinizácia.
Na tomto predmete sa však využíva iná metóda, vytváranie prechodových grafov , ktorá je uvedená v animovanej prezentácii. Táto metóda má tú výhodu, že pomocou nej je možné vytvoriť priamo deterministický konečnostavový automat a nie je potrebná ďalšia determinizácia. Je ju však možné použiť len vtedy, ak množinu vstupných reťazcov pre konečnostavový automat je možné definovať prostredníctvom regulárnych výrazov.
Príklad
Nájdite DKA, ktorý reprezentuje regulárny výraz pre jazyk binárnych numerálov 0|1{0|1}
.
Riešenie
Postupovať budeme nasledujúcim spôsobom.
-
Pre daný regulárny výraz nakreslíme prechodový diagram:
Obr. 2: Prechodový diagram pre regulárny výraz 0|1{0|1}
-
Určíme počiatočný stav $q_0$ umiestnením tokenu: Stav $q_0 = \textcolor{red}{\bullet}$
0|
$\textcolor{red}{\bullet}$1{0|1}
Obr. 3: Počiatočný stav -
Vygenerujeme jednotlivé stavy pomocou prechodovej funkcie $\delta$:
-
$\delta(q_0, 0) = q_1$, dostávame stav $q_1 =$
0|1{0|1}
$\textcolor{red}{\bullet}$ (koncový stav)Obr. 4: Zmena stavu na $q_1$ -
$\delta(q_0, 1) = q_2$, dostávame stav $q_2 =$
0|1{
$\textcolor{red}{\bullet}$0|
$\textcolor{red}{\bullet}$1}
$\textcolor{red}{\bullet}$ (koncový stav)Obr. 5: Zmena stavu na $q_2$ -
$\delta(q_1, 0) = \bot$, prechod nie je definovaný
-
$\delta(q_1, 1) = \bot$, podobne ako v predošlom prípade
-
$\delta(q_2, 0) = q_2$,
-
$\delta(q_2, 1) = q_2$
- Zostavíme tabuľku pre prechodovú funkciu:
stav | 0 | 1 |
---|---|---|
$q_0$ | $q_1$ | $q_2$ |
$q_1$ | $\bot$ | $\bot$ |
$q_2$ | $q_2$ | $q_2$ |
- Z prechodovej tabuľky nakreslíme diagram DKA:
Obr. 6: DKA pre regulárny výraz 0|1{0|1}
Poznámka
Symbolom $\bot$ označujeme nedefinovanú hodnotu.
Príklad
Vykonajte výpočty na základe vyššie uvedeného DKA nad slovami $\varepsilon$, $01$, $101$.
Riešenie
a) $(q_0,\varepsilon)$
Ide o špeciálny prípad výpočtu kedy, začiatočná konfigurácia je zároveň poslednou konfiguráciou výpočtu. Tá však nie je akceptujúca, keďže stav $q_0$ nie je koncový. Slovo $\varepsilon$ preto nie je akceptované.
b) $(q_0,01)\vdash(q_1,1)$
Slovo $01$ nie je akceptované, hovoríme že automat sa zasekol v konfigurácii $(q_1,1)$.
c) $(q_0,101)\vdash(q_2,01)\vdash(q_2,1)\vdash(q_2,\varepsilon)$
Slovo $101$ je akceptované.
Precvičte si vytváranie deterministického konečnostavového akceptora na základe zadaného regulárneho výrazu s využitím metódy vytvárania prechodových grafov na nasledujúcich príkladoch:
Úloha 3.1
Vytvorte prechodový diagram regulárneho výrazu a[a]{b}b
a zostavte jemu zodpovedajúci DKA. Na báze zostaveného DKA zistite či slová $abbb$, $aaa$ patria do takto špecifikovaného jazyka.
Úloha 3.2
Vytvorte prechodový diagram regulárneho výrazu [c]{ab}c
a zostavte jemu zodpovedajúci DKA. Na báze zostaveného DKA zistite či slová $ababc$, $caba$ patria do takto špecifikovaného jazyka.
Úloha 3.3
Vytvorte prechodový diagram regulárneho výrazu {b}[c]ba
a zostavte jemu zodpovedajúci DKA. Na báze zostaveného DKA zistite či slová $bbca$, $cba$ patria do takto špecifikovaného jazyka.
Úloha 3.4
Vytvorte prechodový diagram regulárneho výrazu a{ab}a[ab]b
a zostavte jemu zodpovedajúci DKA. Na báze zostaveného DKA zistite či slová $aababb$, $aaa$ patria do takto špecifikovaného jazyka.
Krok 4
V predchádzajúcom kroku tohto cvičenia sme sa naučili, ako z regulárneho výrazu priamo vytvoriť DKA. V tomto kroku sa oboznámime s dvoma základnými prístupmi k jeho praktickej implementácii, a to:
- neiteratívnym a
- iteratívnym prístupom.
Najprv sa teda oboznámime so všeobecným princípom neiteratívnej implementácie DKA.
Vstupom implementácie je reťazec a výstupom je informácia, či reťazec patrí alebo nepatrí do jazyka, teda pravdivostná hodnota.
Každý stav $q_i \in Q$ bude v rámci tejto implementácie zodpovedať funkcii
$\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad$q_i:String -> Bool
,
t. j. funkcii, ktorá na vstupe prijíma reťazec a na výstupe produkuje pravdivostnú hodnotu, pri implementácii ktorej sa riadime nasledujúcimi pravidlami:
- Funkcia
q_i
vráti pravdivostnú hodnotuTrue
, akq_i
zodpovedá koncovému stavu DKA a jej argumentom je prázdny reťazec $\varepsilon$. - Funkcia
q_i
na základe prvého symbolu $x$ jej odovzdaného slova $xw_r$ vráti výsledok volania funkcieq_j
s argumentom $w_r$, ak pre prechodovú funkciu implementovaného DKA platí $\delta(q_i,x)=q_j$. - Vo všetkých ostatných prípadoch vráti funkcia
q_i
pravdivostnú hodnotuFalse
.
Volaním funkcie q_0
zodpovedajúcej počiatočnému stavu implementovaného DKA s argumentom predstavujúcim kontrolované slovo spustíme samotný výpočet DKA. Keďže tento prístup využíva pre spracovanie symbolov vstupného reťazca postupné volanie funkcií zodpovedajúcich jednotlivým stavom implementovaného DKA ide o neiteratívny prístup k jeho implementácii.
/*implementácia funkcie zodpovedajúcej koncovému
stavu qi*/
bool q_i(char* word){
if (strlen(word)==0){
return true;
}else{
switch (word[0]){
case 'j':
return q_j(&word[1]);
/*...*/
case 'k':
return q_k(&word[1]);
default:
return false;
}
}
}
/*implementácia funkcie zodpovedajúcej stavu qi*/
bool q_i(char* word){
if (strlen(word)>0){
switch (word[0]){
case 'j':
return q_j(&word[1]);
/*...*/
case 'k':
return q_k(&word[1]);
default:
return false;
}
}
return false;
}
Okrem vyššie uvedeného prístupu môžno zvoliť aj štandardnejší iteratívny prístup k implementácii DKA, kedy aktuálny stav automatu predstavuje internu premennú, ktorá sa pri postupnom čítaní jednotlivých symbolov vstupného slova (teda pri iterácii týmto slovom) mení na základe prechodovej funkcie $\delta$. Ak sa po prečítaní celého slova v tejto internej premennej nacháda koncový stav, slovo je akceptované, v opačnom prípade slovo nebude akceptované. Slovo nebude akceptované taktiež v prípade, ak funkcia $\delta$ neposkytne žiadny nový stav po prečítaní niektorého zo symbolov slova.
Úloha 4.1
Podľa pokynov vyučujúceho samostatne implementuje DKA pre regulárny výraz binárnych numerálov. Zohľadnite skutočnosť, že na vstupe môže byť ľubovoľný reťazec. Váš program by mal vedieť rozoznať jazyk binárnych numerálov v zadanom reťazci. Prediskutujte realizované riešenie.
Úloha 4.2
Akú základnú programovaciu techniku reprezentuje slučka (prechod resp. výpočet tvaru $(q,xw)\vdash^{1}(q,w)$) v diagrame DKA v prípade jeho neiteratívnej implementácie? Možno túto techniku zachytiť aj iným typom výpočtu v DKA?
Úloha 4.3
Podľa pokynov vyučujúceho samostatne implementuje DKA pre vybrané regulárny výrazy z predchádzajúceho kroku. Prediskutujte realizované riešenie.
Doplňujúce úlohy
Úloha A.1
Prejdite si príklady na vytváranie regulárnych výrazov v zbierke od č. 1.13
Úloha A.2
Samostatne vyriešte príklady na vytváranie DKA v zbierke od č. 3.1 - precvičte si ich pomocou metódy vytvárania prechodových diagramov.
Úloha A.3
Precvičiť znalosti regulárnych výrazov (v ich bežnejšom zápise) môžete aj pomocou krížoviek. Skúste si niektoré regulárne výrazy z krížoviek prepísať do zápisu používaného na tomto cvičení.
Dotazník na ohodnotenie učiva
Vážení študenti,
poprosili by som Vás o vyplnenie tohto dotazníka .
Tento dotazník slúži na ohodnotenie vašich skúseností s pripravenými materiálmi z druhého cvičenia. Na vylepšovaní učiva sa aktívne pracuje a Vaše odpovede nám pomôžu zlepšiť kvalitu výučby.