<h1class="title">Zadávání formalismů pro popis regulárních jazyků</h1>
</header>
<h2id="konečné-automaty-dfa-nfa-nfa-s-ε-kroky">Konečné automaty (DFA, NFA, NFA s ε-kroky)</h2>
<p>Pro popis konečného automatu je třeba zapsat iniciální stav, přechodovou funkci a množinu koncových stavů.</p>
<p>Pro popis konečného automatu je třeba zapsat iniciální stav, přechodovou funkci a množinu koncových stavů. Validní automat musí obsahovat alespoň jeden (iniciální) stav.</p>
<p>Počáteční stav lze explicitně definovat jako <code>init=stav</code> na počátku zápisu automatu. Není-li počáteční stav takto specifikován, pak je jako počáteční stav vyhodnocen ten, který se jako první objeví v přechodové funkci.</p>
<p>Přechodová funkce sestává z pravidel ve tvaru:</p>
<p>Přechodová funkce sestává z přechodů zapsaných ve tvaru:</p>
<ul>
<li><code>(vstupní_stav,znak)=výstupní_stav</code> pro deterministické automaty,</li>
<li><code>(vstupní_stav,znak)={výstupní_stav1,výstupní_stav2, ..., výstupní_stavN}</code> pro nedeterministické automaty.</li>
</ul>
<p>V nedeterminstických automatech s ε-kroky lze místo znaku v přechodové funkci zapsat přechod pod prázdným slovem pomocí znaku <code>ε</code> nebo <code>\e</code>. Není vhodné uvádět pro stejnou dvojici <code>(vstupní_stav,znak)</code> v přechodové funkci více přechodů než jeden, vyhodnocovací služba v takovém případě bude brát v úvahu jenom poslední zaznamenaný přechod a upozorní na možný problém.</p>
<p>Zápis množiny koncových stavů je <code>final={koncový_stav1,koncový_stav2, ..., koncový_stavN}</code>, je na samém konci zápisu a nelze jej vynechat.</p>
<p>Validní automat musí obsahovat alespoň jeden stav.</p>
<p>V názvech stavů a znaků lze použít malá i velká písmena anglické abecedy, číslice <code>0–9</code> a znaky <code>_</code> a <code>'</code>. Lze tvořit i víceznakové sekvence jako názvy stavů. Bílé znaky (mezera, tab, konec řádku) mezi jednotlivými identifikátory nemají na vyhodnocení automatu vliv, nelze je však použít uvnitř názvů stavů nebo znaků.</p>
<p>Zápis množiny koncových stavů je <code>final={koncový_stav1,koncový_stav2, ..., koncový_stavN}</code>, je na samém konci zápisu, oddělen aspoň jedním bílým znakem (mezera, tab, konec řádku) od přechodové funkce, a nelze jej vynechat.</p>
<p>Jako názvy stavů a znaků (identifikátory) lze použít:</p>
<ul>
<li>malá i velká písmena anglické abecedy, číslice <code>0–9</code>, znaky <code>_</code> a <code>'</code> nebo víceznakovou sekvenci uvedených symbolů,</li>
<li>sekvenci jakýchkoli znaků kromě uvozovek a bílých znaků uzavřenou v uvozovkách (např. stav <code>"{A,B,C}"</code>).</li>
</ul>
<p>Bílé znaky mezi jednotlivými identifikátory nemají na vyhodnocení automatu vliv, nelze je však použít uvnitř názvů stavů nebo znaků.</p>
<h3id="kanonický-automat">Kanonický automat</h3>
<p>Vyžaduje-li zadání úlohy kanonizaci automatu, použijte při pojmenovávání velká písmena anglické abecedy v lexikografickém pořadí. V případě potřeby více než 26 stavů následují vícemístné kombinace písmen: A, B, …, Y, Z, AA, AB, …, AZ, BA, BB, …, ZY, ZZ, AAA, AAB, … (jde o bijektivní poziční soustavu s bází 26).</p>
<h3id="příklady">Příklady:</h3>
<ul>
<li><code>init=0 (0,a)=1 (0,b)=1 final={0,1}</code> (DFA s počátečním stavem <code>0</code>)</li>
<li><code>(q_0, a) = q_1 (q_0, b) = q_1 (q_1, a) = q_1 final = {q_1}</code> (DFA s počátečním stavem <code>q_0</code>)</li>
<li><code>init=init (init,a)={fst,snd} (fst,b)={snd} (snd,b)={fst} final={fst,snd}</code> (NFA s počátečním stavem <code>init</code>)</li>
<li><code>init=in (in,a)={fst,snd} (fst,b)={snd} (snd,b)={fst} final={fst,snd}</code> (NFA s počátečním stavem <code>in</code>)</li>
<li><code>(0,ε)={1} final={}</code> (NFA s epsilon kroky, počátečním stavem <code>init</code> a žádnými koncovými stavy)</li>
<li><code>(A,a)=B (A,b)=C</code><br/>
<code>(B,a)=A (B,b)=B</code><br/>
<code>(C,a)=C (C,b)=A</code><br/>
<li><code>(A,"(a)")=B (A,b)=C</code><br/>
<code>(B,"(a)")=A (B,b)=B</code><br/>
<code>(C,"(a)")=C (C,b)=A</code><br/>
<code>final={A}</code> (DFA s počátečním stavem <code>A</code>)</li>
</ul>
<h2id="regulární-výrazy">Regulární výrazy</h2>
<p>Základní regulární výrazy jsou znak, prázdné slovo a prázdný jazyk:</p>
<ul>
<li>jako znaky lze použít malá i velká písmena anglické abecedy a číslice <code>0–9</code>,</li>
<li>jako znaky lze použít malá i velká písmena anglické abecedy, číslice <code>0–9</code> nebo také sekvence jakýchkoliv znaků v uvozovkách (kromě uvozovek a bílých znaků),</li>
<li>prázdné slovo (epsilon) se značí jako <code>\e</code> nebo <code>ε</code>,</li>
<li>prázdný jazyk je možné zapsat jako <code>\0</code> nebo <code>∅</code>.</li>
<li>prázdný jazyk je možné zapsat jako <code>\0</code>(nula) nebo <code>∅</code>.</li>
</ul>
<p>Další regulární výrazy vznikají použitím operací iterace, zřetězení a sjednocení:</p>
<ul>
<li>regulární výraz je možné iterovat operátory <code>^*</code> (iterace) a <code>^+</code> (pozitivní iterace), jako iterovaný se vyhodnotí nejbližší znak nebo regulární výraz v nejbližší závorce (nejblíže operátoru zleva),</li>
<li>regulární výraz je možné použít operátory <code>^*</code> (iterace) a <code>^+</code> (pozitivní iterace), jako iterovaný se vyhodnotí nejbližší znak nebo regulární výraz v nejbližší závorce (nejblíže operátoru zleva),</li>
<li>každé dva regulární výrazy lze zřetězit operátorem <code>.</code>,</li>
<li>operaci <code>+</code>, která sémanticky odpovídá sjednocení dvou regulárních výrazů, lze zapsat pomocí operátoru <code>+</code>.</li>
</ul>
...
...
@@ -66,20 +70,21 @@
<li><code>(a + b + c^*) + \e</code> je ekvivalentní s <code>a + b + (c)^* + ε</code></li>
<p>Z gramatiky stačí definovat množinu pravidel, iniciálním neterminálem je první vyskytující se neterminál. Pravidla regulární gramatiky mohou být tvaru:</p>
<ul>
<li><code>Neterminál -> TerminálNeterminál</code> (např. <code>A -> aA</code>),</li>
<li><code>Neterminál -> Terminál</code> (např. <code>B -> b</code>),</li>
<li><code>Neterminál -> ε</code> (např. <code>S -> ε</code>),</li>
</ul>
<p>Pokud regulární gramatika generuje prázdné slovo (ε), pak lze v pravidle použít symbol <code>ε</code> nebo <code>\e</code> (ovšem pouze u iniciálního neterminálu, který se v tomto případě nesmí objevit v pravé straně žádného z pravidel). Pravidla pro různé neterminály je třeba oddělit středníkem nebo koncem řádku. Jako šipku lze psát <code>-></code> i unicodový znak <code>→</code>. Více přepisovacích pravidel se stejnou levou stranou lze zapsat také pomocí oddělovače <code>|</code> (např. <code>A -> aA | b</code>).</p>
<p>Z gramatiky stačí definovat množinu pravidel, iniciálním neterminálem je první vyskytující se neterminál.</p>
<p>Neterminál je tvořen:</p>
<ul>
<li>jedním velkým písmenem anglické abecedy (např. <code>S</code>, <code>A</code>),</li>
<li>sekvencí malých a velkých písmen anglické abecedy, číslic nebo znaku <code>_</code> uzavřenou do lomených závorek <code><></code> (např. <code><abAB></code>, <code><S_0></code>),</li>
<li>sekvencí malých a velkých písmen anglické abecedy, číslic nebo znaku <code>_</code> uzavřenou do lomených závorek <code><</code>, <code>></code> (např. <code><a></code>, <code><abAB></code>, <code><S_0></code>),</li>
<li>jedním malým písmenem anglické abecedy nebo předchozím typem neterminálu (velké písmeno, sekvence v závorkách) s jedním nebo více apostrofy (např. <code>S'</code>, <code>a''</code>, <code><aB_0>'</code>).</li>
</ul>
<p>Terminálem může být jedno malé písmeno anglické abecedy nebo číslice <code>0–9</code>.</p>
<p>Terminálem může být jedno malé písmeno anglické abecedy, číslice <code>0–9</code> nebo sekvence jakýchkoliv znaků (kromě <code>"</code> a bílých znaků) v uvozovkách.</p>
<p>Pravidla regulární gramatiky mohou být tvaru:</p>
<ul>
<li><code>Neterminál -> TerminálNeterminál</code> (např. <code>A -> aA</code>),</li>
<li><code>Neterminál -> Terminál</code> (např. <code>B -> b</code>),</li>
<li><code>Neterminál -> ε</code> (např. <code>S -> ε</code>), ovšem pouze u iniciálního neterminálu, který se v tomto případě nesmí objevit v pravé straně žádného z pravidel.</li>
</ul>
<p>Jako prázdné slovo (ε) lze psát <code>ε</code> nebo <code>\e</code>. Pravidla pro různé neterminály je třeba oddělit čárkou, středníkem nebo koncem řádku. Jako šipku lze psát <code>-></code> i unicodový znak <code>→</code>. Více přepisovacích pravidel se stejnou levou stranou lze zapsat také pomocí oddělovače <code>|</code> (např. <code>A -> aA | b</code>). Mezery a taby lze mimo názvů terminálů a neterminálů používat libovolně (konec řádku však odděluje pravidla).</p>
<h3id="příklady-2">Příklady</h3>
<ul>
<li><code>S -> aS | aA | a; A -> bA | aS</code></li>
@@ -6,22 +6,25 @@ title: Zadávání formalismů pro popis regulárních jazyků
## Konečné automaty (DFA, NFA, NFA s ε-kroky)
Pro popis konečného automatu je třeba zapsat iniciální stav, přechodovou funkci a množinu koncových stavů.
Pro popis konečného automatu je třeba zapsat iniciální stav, přechodovou funkci a množinu koncových stavů. Validní automat musí obsahovat alespoň jeden (iniciální) stav.
Počáteční stav lze explicitně definovat jako `init=stav` na počátku zápisu automatu. Není-li počáteční stav takto specifikován, pak je jako počáteční stav vyhodnocen ten, který se jako první objeví v přechodové funkci.
Přechodová funkce sestává z pravidel ve tvaru:
Přechodová funkce sestává z přechodů zapsaných ve tvaru:
*`(vstupní_stav,znak)=výstupní_stav` pro deterministické automaty,
*`(vstupní_stav,znak)={výstupní_stav1,výstupní_stav2, ..., výstupní_stavN}` pro nedeterministické automaty.
V nedeterminstických automatech s ε-kroky lze místo znaku v přechodové funkci zapsat přechod pod prázdným slovem pomocí znaku `ε` nebo `\e`. Není vhodné uvádět pro stejnou dvojici `(vstupní_stav,znak)` v přechodové funkci více přechodů než jeden, vyhodnocovací služba v takovém případě bude brát v úvahu jenom poslední zaznamenaný přechod a upozorní na možný problém.
Zápis množiny koncových stavů je `final={koncový_stav1,koncový_stav2, ..., koncový_stavN}`, je na samém konci zápisu a nelze jej vynechat.
Zápis množiny koncových stavů je `final={koncový_stav1,koncový_stav2, ..., koncový_stavN}`, je na samém konci zápisu, oddělen aspoň jedním bílým znakem (mezera, tab, konec řádku) od přechodové funkce, a nelze jej vynechat.
Validní automat musí obsahovat alespoň jeden stav.
Jako názvy stavů a znaků (identifikátory) lze použít:
V názvech stavů a znaků lze použít malá i velká písmena anglické abecedy, číslice `0–9` a znaky `_` a `'`. Lze tvořit i víceznakové sekvence jako názvy stavů. Bílé znaky (mezera, tab, konec řádku) mezi jednotlivými identifikátory nemají na vyhodnocení automatu vliv, nelze je však použít uvnitř názvů stavů nebo znaků.
* malá i velká písmena anglické abecedy, číslice `0–9`, znaky `_` a `'` nebo víceznakovou sekvenci uvedených symbolů,
* sekvenci jakýchkoli znaků kromě uvozovek a bílých znaků uzavřenou v uvozovkách (např. stav `"{A,B,C}"`).
Bílé znaky mezi jednotlivými identifikátory nemají na vyhodnocení automatu vliv, nelze je však použít uvnitř názvů stavů nebo znaků.
### Kanonický automat
...
...
@@ -30,24 +33,24 @@ Vyžaduje-li zadání úlohy kanonizaci automatu, použijte při pojmenováván
### Příklady:
*`init=0 (0,a)=1 (0,b)=1 final={0,1}` (DFA s počátečním stavem `0`)
*`(q_0, a) = q_1 (q_0, b) = q_1 (q_1, a) = q_1 final = {q_1}` (DFA s počátečním stavem `q_0`)
*`init=init (init,a)={fst,snd} (fst,b)={snd} (snd,b)={fst} final={fst,snd}` (NFA s počátečním stavem `init`)
*`init=in (in,a)={fst,snd} (fst,b)={snd} (snd,b)={fst} final={fst,snd}` (NFA s počátečním stavem `in`)
*`(0,ε)={1} final={}` (NFA s epsilon kroky, počátečním stavem `init` a žádnými koncovými stavy)
*`(A,a)=B (A,b)=C`
`(B,a)=A (B,b)=B`
`(C,a)=C (C,b)=A`
*`(A,"(a)")=B (A,b)=C`
`(B,"(a)")=A (B,b)=B`
`(C,"(a)")=C (C,b)=A`
`final={A}` (DFA s počátečním stavem `A`)
## Regulární výrazy
Základní regulární výrazy jsou znak, prázdné slovo a prázdný jazyk:
* jako znaky lze použít malá i velká písmena anglické abecedy a číslice `0–9`,
* jako znaky lze použít malá i velká písmena anglické abecedy, číslice `0–9` nebo také sekvence jakýchkoliv znaků v uvozovkách (kromě uvozovek a bílých znaků),
* prázdné slovo (epsilon) se značí jako `\e` nebo `ε`,
* prázdný jazyk je možné zapsat jako `\0` nebo `∅`.
* prázdný jazyk je možné zapsat jako `\0`(nula) nebo `∅`.
Další regulární výrazy vznikají použitím operací iterace, zřetězení a sjednocení:
* regulární výraz je možné iterovat operátory `^*` (iterace) a `^+` (pozitivní iterace), jako iterovaný se vyhodnotí nejbližší znak nebo regulární výraz v nejbližší závorce (nejblíže operátoru zleva),
* regulární výraz je možné použít operátory `^*` (iterace) a `^+` (pozitivní iterace), jako iterovaný se vyhodnotí nejbližší znak nebo regulární výraz v nejbližší závorce (nejblíže operátoru zleva),
* každé dva regulární výrazy lze zřetězit operátorem `.`,
* operaci `+`, která sémanticky odpovídá sjednocení dvou regulárních výrazů, lze zapsat pomocí operátoru `+`.
...
...
@@ -62,21 +65,24 @@ Operace jsou seřazeny podle priority od nejvyšší po nejnižší, nejdříve
## Regulární gramatiky
Z gramatiky stačí definovat množinu pravidel, iniciálním neterminálem je první vyskytující se neterminál. Pravidla regulární gramatiky mohou být tvaru:
*`Neterminál -> TerminálNeterminál` (např. `A -> aA`),
*`Neterminál -> Terminál` (např. `B -> b`),
*`Neterminál -> ε` (např. `S -> ε`),
Pokud regulární gramatika generuje prázdné slovo (ε), pak lze v pravidle použít symbol `ε` nebo `\e` (ovšem pouze u iniciálního neterminálu, který se v tomto případě nesmí objevit v pravé straně žádného z pravidel). Pravidla pro různé neterminály je třeba oddělit středníkem nebo koncem řádku. Jako šipku lze psát `->` i unicodový znak `→`. Více přepisovacích pravidel se stejnou levou stranou lze zapsat také pomocí oddělovače `|` (např. `A -> aA | b`).
Z gramatiky stačí definovat množinu pravidel, iniciálním neterminálem je první vyskytující se neterminál.
Neterminál je tvořen:
* jedním velkým písmenem anglické abecedy (např. `S`, `A`),
* sekvencí malých a velkých písmen anglické abecedy, číslic nebo znaku `_` uzavřenou do lomených závorek `<>` (např. `<abAB>`, `<S_0>`),
* sekvencí malých a velkých písmen anglické abecedy, číslic nebo znaku `_` uzavřenou do lomených závorek `<`, `>` (např. `<a>`, `<abAB>`, `<S_0>`),
* jedním malým písmenem anglické abecedy nebo předchozím typem neterminálu (velké písmeno, sekvence v závorkách) s jedním nebo více apostrofy (např. `S'`, `a''`, `<aB_0>'`).
Terminálem může být jedno malé písmeno anglické abecedy nebo číslice `0–9`.
Terminálem může být jedno malé písmeno anglické abecedy, číslice `0–9` nebo sekvence jakýchkoliv znaků (kromě `"` a bílých znaků) v uvozovkách.
Pravidla regulární gramatiky mohou být tvaru:
*`Neterminál -> TerminálNeterminál` (např. `A -> aA`),
*`Neterminál -> Terminál` (např. `B -> b`),
*`Neterminál -> ε` (např. `S -> ε`), ovšem pouze u iniciálního neterminálu, který se v tomto případě nesmí objevit v pravé straně žádného z pravidel.
Jako prázdné slovo (ε) lze psát `ε` nebo `\e`. Pravidla pro různé neterminály je třeba oddělit čárkou, středníkem nebo koncem řádku. Jako šipku lze psát `->` i unicodový znak `→`. Více přepisovacích pravidel se stejnou levou stranou lze zapsat také pomocí oddělovače `|` (např. `A -> aA | b`). Mezery a taby lze mimo názvů terminálů a neterminálů používat libovolně (konec řádku však odděluje pravidla).