Ciele
- Oboznámiť sa s organizáciou cvičení predmetu Formálne jazyky a podmienkami udelenia zápočtu.
- Definovať základné pojmy teórie formálnych jazykov.
- Oboznámiť sa s regulárnymi výrazmi.
- Prakticky precvičiť zostavenie vybraných regulárnych výrazov.
Úvod
Na tomto cvičení sa oboznámite s organizáciou cvičení a podmienkami udelenia priebežného hodnotenia (zápočtu). Následne predstavíme úvod do formálnych jazykov, približíme základné pojmy, a oboznámime sa s operáciami nad jazykmi a ich abecedami. V poslednom kroku priblížime koncept regulárnych výrazov, ich konštrukcie a grafickej reprezentácie prostredníctvom prechodových diagramov. Tieto zručnosti prakticky overíme na konkrétnych príkladoch.
Postup
Krok 1
Oboznámte sa s organizáciou cvičení predmetu Formálne jazyky a podmienkami udelenia zápočtu.
Krok 2
Jazyk je základným komunikačným prostriedkom nielen v interpersonálnej komunikácii ale taktiež pri komunikácii človeka s výpočtovým systémom. V prípade druhej z vyššie uvedených situácií však nemožno predpokladať realizáciu komunikácie v tak syntakticky a sémanticky voľnej forme, ako poskytujú práve prirodzené jazyky. To podnietilo vznik počítačových (formálnych) jazykov a intenzívny výskum v tejto oblasti.
Štandardne rozoznávame tri základné roviny jazyka:
- syntaktickú,
- sémantickú a
- fonetickú.
Keďže fonetická rovina je vlastná len prirodzeným jazykom, pri štúdiu formálnych jazykov sa možno uberať dvoma smermi, a to štúdiom ich syntaxe alebo sémantiky. Americký lingvista Noam Chomsky, jedna z najvýznamnejších osobností tejto výskumnej oblasti, výrazne prispel k všeobecne prijatej idei primátu syntaxe. Na tomto základe sa dnes preto pod pojmom teórie formálnych jazykov rozumie výlučne štúdium ich syntaktických zákonitostí.
Teraz sa zoznámime so základnými pojmami teórie formálnych jazykov.
Abeceda $A$ je konečná neprázdna množina prvkov nazývaných symboly. Abecedou môže byť napríklad:
- $\{a, b, \ldots, z\}$ – abeceda pozostávajúca z malých latinských písmen,
- $\{0, 1\}$ – abeceda binárnych čísel,
- $\{0, 1, \ldots, 9, A, B, \ldots, F\}$ – abeceda haxadecinálnych čísel,
- $\{\mathtt{if}, \mathtt{else}, \mathtt{while}, \mathtt{if}, *, +, -, \ldots \}$ – množina lexikálnych elementov jednoduchého programovacieho jazyka.
Reťazec $w$ nad abecedou $A$, taktiež označovaný ako slovo resp. veta je ľubovoľná postupnosť symbolov abecedy.
- Počet symbolov v reťazci $w$ nazývame dĺžkou reťazca a označujeme $|w|$.
- Špeciálny prípad reťazca je tzv. prázdny reťazec označovaný $\varepsilon$, pre ktorého dĺžku platí:
$$ |\varepsilon| = 0. $$
- Ak $ w = a_1 \ldots a_n $ je reťazec nad abecedou $A$, potom obrátený reťazec k reťazcu $w$ je reťazec
$$ w^R = a_n \ldots a_1. $$
- Reťazce možno spájať prostredníctvom binárnej operácie zreťazenia. Nech $w_1 = a_1...a_j$ a $w_2 = b_1...b_k$ sú reťazce nad abecedou $A$. Potom zreťazenie reťazcov $w_1$ a $w_2$ je reťazec $w_1\cdot w_2$ (alebo skrátene $w_1w_2$), pre ktorý platí:
$$ w_1 w_2 = a_1 \ldots a_j b_1 \ldots b_k .$$ Operácia zreťazenia nie je komutatívna t. j. neplatí $w_1w_2 \neq w_2w_1$.
- Ďalšou v tomto prípade však unárnou operáciou nad reťazcami je $n$-tá mocnina reťazca $w^n$. Ak $w$ je reťazec a $n\in \mathbb{N}_0$, potom reťazec
$$ w^n = \underbrace{ww\ldots w}_{n\text{-}krát}$$ je reťazec, ktorý vznikne zreťazením $n$ kópií reťazca $w$. Keďže mocnina reťazca má vyššiu prioritu ako zreťazenie, slovo $abc^2$ tak predstavuje slovo $abcc$ a nie slovo $abcabc$, ktoré by sme museli zapísať $(abc)^2$. Nultá mocnina ľubovoľného reťazca je prázdny reťazec, $$w^0 = \varepsilon,$$ čo je špecifický prípad mocniny reťazca.
- Ak $w_1, w_2, w_3$ sú tri reťazce, potom $w_1$ je predponou (prefix), $w_2$ je podreťazcom a $w_3$ je príponou (sufix) reťazca $w_1w_2w_3$.
Poznámka
Dôležité je uvedomiť si skutočnosť, že predpona $w_1$ a prípona $w_3$ sú taktiež podreťazce reťazca $w_1w_2w_3$.
Poznámka
Prázdny reťazec je predponou, príponou a podreťazcom každého reťazca, dokonca aj prázdneho reťazca.
Úloha 2.1
Nech sú dané dva reťazce $w_1 = abc$ a $w_2 = abbc$.
a) Určte najmenšiu možnú (minimálnu) abecedu týchto reťazcov.
b) Určte dľžky oboch reťazcov $w_1$ a $w_2$.
c) Určte obrátený reťazec k reťazcu $w_2$.
d) Určte dĺžku reťazca $w_2 \varepsilon w_1 \varepsilon.$
e) Sú reťazce $w_2\varepsilon$ a $\varepsilon w_2$ zhodné s reťazcom $w_2$?
f) Platí, že $w_1^Rw_2^R=(w_2w_1)^R$?
g) Absolútne určte reťazce $w_1^2$ a $w_2^3$.
h) Relatívne a absolútne určte reťazec, ktorý vznikne ako výsledok druhej mocniny zreťazenia nultej mocniny reťazca $w_1$ a tretej mocniny obrátenia reťazca $w_2$.
i) Ktoré reťazce sú zároveň predponou aj príponou reťazca $101110110$?
Kleeneho uzáver resp. tranzitívny uzáver $A^*$ je množina všetkých reťazcov nad abecedou $A$. Pozitívny uzáver $A^+$ je množina všetkých neprázdnych reťazcov nad abecedou A. Platí teda
$$ A^+ = A^* - \{\varepsilon\}.$$
Formálny jazyk $L$ je ľubovoľná podmnožina množiny všetkých možných reťazcov nad abecedou tohto jazyka $A$,
$$L \subseteq A^*.$$
- Nech $L_1$, $L_2$ sú jazyky. Potom zreťazením týchto jazykov nazývame jazyk
$$ L_1 \cdot L_2 = \{ w_1w_2\;|\; w_1 \in L_1 \land w_2 \in L_2 \}. $$
- Nech $L$ je jazyk. Potom jeho $n$-tou mocninou $L^n$ (pre $n\in\mathbb{N}_0$) nazývame jazyk definovaný takto:
$$ L^0 = \{ \varepsilon \}, \text{ pre } n=0,$$ $$ L^{n} = L \cdot L^{n-1}, \text{ pre } n>0,$$ čo znamená, že jazyk $ L^{n} $ sa skladá zo všetkých reťazcov, ktoré vzniknú zreťazením reťazcov jazyka $L$ s reťazcami jazyka $ L^{n-1}$.
- Iterácia (Kleeneho uzáver) jazyka $L$ je jazyk $L^*$, ktorý vznikne zjednotením všetkých celých nezáporných mocnín jazyka $L$,
$$L^*=\cup_{n=0}^{\infty}L^n.$$
- Pozitívna iterácia jazyka $L$ je jazyk $L^+$, ktorý vznikne zjednotením všetkých prirodzených mocnín jazyka $L$,
$$L^+=\cup_{n=1}^{\infty}L^n.$$
- Nech $L_1$, $L_2$ sú jazyky. Ich zjednotením je jazyk, ktorý obsahuje všetky reťazce z $L_1$ a všetky reťazce z $L_2$,
$$L_1 \cup L_2 = \{w \;|\; w\in L_1 \lor w\in L_2\}.$$
- Nech $L_1$, $L_2$ sú jazyky. Ich prienikom je jazyk, ktorý obsahuje len tie reťazce, ktoré sú súčasne v $L_1$ aj $L_2$,
$$L_1\cap L_2=\{w \;|\; w\in L_1 \land w\in L_2\}.$$
- Nech $L_1$, $L_2$ sú jazyky. Ich rozdielom je jazyk, ktorý obsahuje tie reťazce z $L_1$, ktoré nie sú v $L_2$.
$$L_1−L_2=\{w \;|\; w\in L_1 \land w\not\in L_2\}.$$
- Nech $L$ je jazyk nad abecedou $A$. Potom jeho doplnkom resp. komplementom $L^C$ nazývame jazyk, ktorý obsahuje všetky reťazce nad abecedou $A$, ktoré nepatria do $L$,
$$ L^C = A^* - L.$$
- Nech $L_1$, $L_2$ sú jazyky. Ľavý kvocient jazyka $L_1$ podľa $L_2$ je jazyk, pre ktorý platí:
$$L_2\backslash L_1=\{w_1\;|\;(\exists w_2 \in L_2)(w_2w_1\in L_1)\}.$$
Príklad
Nech je daný jazyk $ L_1 = \{ a, ab \} $ a jazyk $ L_2 = \{\varepsilon, b, ba \} $. Určte zreťazenie týchto jazykov.
Riešenie
$ L_1 L_2 = \{a\cdot\varepsilon, a\cdot b, a\cdot ba, ab\cdot \varepsilon, ab\cdot b, ab\cdot ba\}$ $= \{a, ab, aba, abb, abba \} $
Príklad
Určte prvých päť mocnín jazyka $L=\{a,ab\}$.
Riešenie
- $ L^0 = \{ \varepsilon \} $.
- $ L^1 = \{ a, ab \} $.
- $ L^2 = L \cdot L^1 : $ Zreťazujeme každý reťazec z $ L $ s každým reťazcom z $ L^1 $
$$ L^2 = \{ a \cdot a, a \cdot ab, ab \cdot a, ab \cdot ab \} = \{ aa, aab, aba, abab \}. $$
- $ L^3 = L \cdot L^2 : $ Zreťazujeme každý reťazec z $ L $ s každým reťazcom z $ L^2 $ $$ L^3 = \{ aaa, aaab, aaba, aabab, abaa, abaab, ababa, ababab \}. $$
- $ L^4 = L \cdot L^3 : $ Zreťazujeme každý reťazec z $ L $ s každým reťazcom z $ L^3 $ $$ L^4 = \{ aaaa, aaaab, aaaba, aaabab, aabaa, aabaab, aababa, aababab, abaaa, abaaab,$$ $$abaaba, abaabab, ababaa, ababaab, abababa, abababab\}. $$
Príklad
Nech sú dané jazyky $L_1=\{baaab, aba, aaa, bbb\}$ a $L_2=\{a\}$. Určte ľavý kvocient jazyka $L_1$ podľa jazyka $L_2$
Riešenie
Keďže jazyk $L_2$ obsahuje len jeden prvok $a$, v jazyku $L_1$ nás budú zaujímať len reťazce s predponou $a$, teda reťazce: $\textcolor{red}{a}ba,\textcolor{red}{a}aa$. Výsledok určime tak, že z týchto reťazcov odtrhneme predponu $\textcolor{red}{a}.$ $L_2\backslash L_1=\{ba,aa\}$
Úloha 2.2
Nech $ L = \{ \varepsilon, a \} $. Určte prvky jazyka $L^3$, dľžku najdlhšieho reťazca tohto jazyka a počet prvkov.
Úloha 2.3
Predpokladajme $ w = xy+ $ . Utvorte zreťazenie reťazca $w$ a druhej mocniny obráteného reťazca $w$.
Úloha 2.4
Kedy je iterácia $L^*$ jazyka $L$ konečným jazykom?
Úloha 2.5
Nech sú dané jazyky $ L_1 = \{ aa, ab, ba, bb \}, L_2 = \{ a, b \}. $ Určte prienik jazyka $L_1$ a druhej mocniny jazyka $L_2$.
Úloha 2.6
Nech $A$ je ľubovoľná abeceda. Určte prvky jazyka $A^* – A^+$ a počet prvkov tohto jazyka.
Úloha 2.7
Určte mohutnosť (počet reťazcov) ľavého kvocientu ľubovoľného jazyka $L$ podľa jazyka $\{\varepsilon\}.$
Keďže formálny jazyk je definovaný ako množina reťazocov nad určitou abecedou $A$, základné (primitívne) spôsoby jeho určenia korešpondujú so základnými spôsobmi úrčenia množiny, a to konkrétne:
- vymenovaným všetkých prvkov a
- určením jeho charakteristickej vlastnosti.
Zatiaľ čo prvý spôsob možno uplatniť len v prípade konečných jazykov, druhý spôsob umožňuje jednoznačne určiť aj nekonečné jazyky, čo ukážeme v nasledujúcom príklade.
Príklad
Určte jazyk $L$ nad abecedou $A=\{a\}$, ktorý pozostáva len z reťazcov tvorených párnym počtom za sebou nasledujúcich výskytov symbolu $a$ a určte všetky prvky tohto jazyka pre ktoré platí $|w|\leq 5$.
Riešenie
$L = \{a^{n}\;|\;n\in \mathbb{N}_0 \land 2\mid n\}$
Prvky jazyka $L$ pre ktoré platí $|w|\leq 5$ sú $\varepsilon, aa, aaaa$.
V rámci tohto predmetu sa však prioritne budeme zaoberať precíznejšími spôsobmi definície jazykov, z ktorých prvým sú regulárne výrazy.
Krok 3
Regulárne výrazy sú základným pojmom v teoretickej informatike a poskytujú stručný formalizmus na opis tzv. regulárnych jazykov, o ktorých si neskôr povieme viac.
Zopakujte si teóriu regulárnych výrazov.
Regulárne výrazy sa môžu zapisovať rôznymi spôsobmi. V tabuľke v druhom stĺpci uvádzame zjednodušený zápis, ktorý sa používa v tomto predmete. V treťom stĺpci je uvedený zápis, s ktorým sa najčastejšie môžeme stretnúť v existujúcich implementáciách regulárnych výrazov. Väčšina zápisov regulárnych výrazov tiež ponúka viaceré skrátené zápisy pre celé skupiny znakov, ako napríklad cifry 0-9
či malé a veľké písmená latinskej abecedy a-z
a A-Z
.
Tvar regulárneho výrazu | Zjednodušený zápis (používaný na tomto predmete) | Zápis bežný v implementáciách | |
---|---|---|---|
prázdny reťazec | ε |
||
symbol | a |
a |
|
postupnosť (zoskupenie) | R ${}_1$R ${}_2$ |
R ${}_1$R ${}_2$ |
|
alternatíva (a alebo b) | R ${}_1$|R ${}_2$ |
R ${}_1$|R ${}_2$ |
|
tranzitívny uzáver (opakovanie nula alebo viackrát) | {R} |
R* |
|
pozitívny uzáver (jeden alebo viac opakovaní) | R{R} |
R+ |
|
voliteľnosť (nula alebo jedenkrát) | [R] |
R? |
Poznámka
Skráteny zápis pre skupinu znakov, ako napríklad 0-9
, je len skratkou zápisu 0|1|3|4|5|6|7|8|9
.
Regulárne výrazy možu mať atomický alebo zložený tvar. Atomické (elementárne) tvary regulárnych výrazov sú nasledujúce:
- $\varepsilon$ je regulárny výraz identifikujúci množinu reťazcov pozostávajúcu z jediného reťazca $\varepsilon$,
- $a$, pre $a\in A$, kde $A$ je abeceda, je regulárny výraz identifikujúci množinu reťazcov pozostávajúcu z jediného reťazca zodpovedajúceho symbolu $a$.
Následne možno pristúpiť k vymenovaniu zložených tvarov regulárnych zýrazov. Nech $R$, $R_1$ a $R_2$ sú reguárne výrazy identifikujúce jazyky $L$, $L_1$ a $L_2$. Potom
- ${R}_1{R}_2$ je regulárny výraz identifikujúci jazyk $L_1\cdot L_2$, napríklad regulárny výraz
ab
identifikuje jazyk pozostávajúci z jediného reťazca $ab$, - ${R}_1|{R}_2$ je regulárny výraz identifikujúci jazyk $L_1\cup L_2$, napríklad regulárny výraz
a|b
identifikuje jazyk pozostávajúci z reťazcov $a$,$b$, - $\{R\}$ je regulárny výraz identifikujúci jazyk $L^*$, napríklad regulárny výraz
{a}
identifikuje jazyk pozostávajúci z reťazcov $\varepsilon$, $a$, $aa$, $aaa, \ldots$, - $R\{R\}$ je regulárny výraz identifikujúci jazyk $L^+$, napríklad regulárny výraz
a{a}
identifikuje jazyk pozostávajúci z reťazcov $a$, $aa$, $aaa, \ldots$ - $[R]$ je regulárny výraz identifikujúci jazyk $L\cup\{\varepsilon\}$, napríklad regulárny výraz
[a]
identifikuje jazyk pozostávajúci z reťazcov $\varepsilon$, $a$.
Poznámka
Postupnosť má vyššiu prioritu ako alternatíva! Preto pozor napr. na prípady podobné tomuto:
ab|c{d} = (ab)|(c{d})
.
Regulárne výrazy je možné zobraziť aj graficky pomocou prechodových diagramov. Princíp zostrojenia takéhoto diagramu je znázornený na nasledujúcom obrázku.
Príklad
Skonštruujte prechodový diagram pre regulárny výraz binárnych numerálov (reťazcov reprezentujúcich binárne čísla).
Riešenie
0|1{0|1}
Začíname konštrukciou prechodových diagramov elementárnych regulárnych výrazov, z ktorých sa daný regulárny výraz skladá. Následne aplikujeme kompozičné pravidla z Obr. 2. za účelom konštrukcie prechodových diagramov zodpovedajúcich jednotlivým zloženým tvarom regulárnych výrazov až pokiaľ nezískane výsledný prechodový diagram.
0
0
a 1
0|1
{0|1}
1
a zložený regulárny výraz {0|1}
1{0|1}
0
a zložený regulárny výrazy 1{0|1}
0|1{0|1}
Príklad
Skonštruujte prechodové diagramy pre regulárne výrazy ab|c{d}
a a(b|c){d}
.
Riešenie
ab|c{d}
ab|c{d}
a(b|c){d}
a(b|c){d}
Krok 4
Úloha 4.1
Skonštruujte regulárny výraz pre všetky reťazce pozostávajúce zo znakov $a$ a $b$, ktorý obsahuje podreťazec $abba$.
Úloha 4.2
Skonštruujte regulárny výraz pre všetky reťazce pozostávajúce zo znakov $x$ a $y$, v ktorých je každý výskyt znaku $y$ bezprostredne nasledovaný postupnosťou troch znakov $x$.
Úloha 4.3
Skonštruujte regulárny výraz pre všetky reťazce pozostávajúce zo znakov $p$ a $q$, ktoré obsahujú nepárny počet znakov $q$.
Úloha 4.4
Skonštruujte regulárny výraz pre overenie zápisu identifikátora.
Zápis identifikátora má nasledujúce vlastnosti:
- identifikátor môže (a nemusí) začínať znakom $,
- následne prvý znak môže byť len malé alebo veľké písmeno latinskej abecedy,
- ďalšie znaky (ak sa v pomenovaní vyskytujú) môžu tvoriť ľubovoľnú kombináciu malých alebo veľkých písmen latinskej abecedy alebo ľubovoľné číslice.
Úloha 4.5
Skonštruujte regulárny výraz pre overenie zápisu rodného čísla (podľa slovenskej legislatívy).
V zápise rodného čísla:
- sa môže vyskytovať oddeľovač '/', prípadne zápis neobsahuje žiaden oddeľovač,
- skupina číslic za oddeľovačom môže mať dĺžku tri alebo štyri znaky,
- pri mesiacoch sa vyskytujú dve možné postupnosti: $01-12$, $51-62$.
Úloha 4.6
Skonštruujte regulárny výraz pre overenie zápisu reálneho čísla.
Zápis čísla má nasledujúce vlastnosti:
- číslo môže byť kladné alebo záporné,
- číslo môže a nemusí obsahovať desatinnú časť,
- číslo musí mať vyjadrenú celú časť na aspoň jednu platnú číslicu,
- ak číslo obsahuje aj desatinnú časť, aj tá musí byť vyjadrená na aspoň jednu platnú číslicu,
- oddeľovač celej a desatinnej časti môže byť znak desatinnej čiarky ',' alebo desatinnej bodky '.'
Ako zabezpečíte, aby numerál neobsahoval nevýznamné nuly zľava?
Úloha 4.7
Zostrojte prechodové diagramy pre regulárne výrazy z predchádzajúcich úloh.
Doplňujúce zdroje
Vizualizačné nástroje znázorňujúce proces rozpoznávania textu na základe regulárnych výrazov využívajúce znázornenie na ich prechodových diagramoch.
Poznámka
Všetky nástroje používajú alternatívny bežný zápis regulárnych výrazov, s ktorým ste sa oboznámili na tomto cvičení. Tento zápis sa nebude používať na cvičeniach ani na skúške, zíde sa však pri implementácii programov. Pred použitím oboch vizualizačných nástrojov odporúčame dôkladne sa oboznámiť so vstupným tvarom regulárnych výrazov, ktoré obidva nástroje používajú.
Dotazník na ohodnotenie učiva
Vážení študenti,
týmto by sme Vás chceli požiadať o poskytnutie spätnej väzby k formátu a obsahu materiálov na cvičenia vo forme vyplnenie nasledujúceho dotazníka .
Tento dotazník slúži na ohodnotenie vašich skúseností s pripravenými materiálmi z prvého cvičenia. Na vylepšovaní materiálov na základe vašej spätnej väzby aktívne pracujeme, a to s cieľom zvýšiť kvalitu, zrozumiteľnosť a prínosnosť výučby.