More actions
Bez shrnutí editace |
Bez shrnutí editace |
||
Riadok 4: | Riadok 4: | ||
== Gramatika == | == Gramatika == | ||
V predošlých pojmoch sa vyskytla aj gramatika. Gramatika <math>G</math> generuje iba slová ktoré patria do jazyka <math>L</math> a žiadne iné. | V predošlých pojmoch sa vyskytla aj gramatika. Gramatika <math>G</math> generuje iba slová ktoré patria do jazyka <math>L</math> a žiadne iné (''syntéza''). | ||
Gramatika je definovaná ako štvorica (<math>G = (N, T, P, S)</math>), kde: | Gramatika je definovaná ako štvorica (<math>G = (N, T, P, S)</math>), kde: |
Verzia z 09:50, 5. január 2025
Ako definujeme a tvoríme pravidlá pre gramatiky vo formálnych jazykoch?
Gramatika
V predošlých pojmoch sa vyskytla aj gramatika. Gramatika generuje iba slová ktoré patria do jazyka a žiadne iné (syntéza).
Gramatika je definovaná ako štvorica (), kde:
- je konečná neprázdna množina neterminálnych symbolov,
- je konečná neprázdna množina terminálnych symbolov, pričom (to znamená, že tieto dve množiny nemajú spoločný žiadny symbol - symbol nemôže byť zároveň aj terminálny aj neterminálny),
- je konečná neprázdna množina pravidiel v tvare , kde:
- ľavá strana pravidiel je ľubovoľný reťazec obsahujúci aspoň jeden neterminálny symbol , a
- pravá strana pravidiel je ľubovoľný reťazec ,
- je začiatočný neterminálny symbol.
Definícia môže vyzerať naozaj strašne pre niekoho kto nevie čítať matematické zápisy. V takom prípade stačí, ak si zapamätá:
- Pomocou gramatiky generujeme nejaké slovo ktoré jednoznačne patrí iba do jedného konkrétneho jazyka (napríklad: môžeme definovať gramatiku pre generovanie čísiel od 0 po 9 a naše pravidlá zabezpečia že výsledok bude vždy iba nejaké číslo, nie napríklad písmeno);
- Gramatika funguje tak, že najskôr definujeme pravidlá pre postupné nahrádzanie dočasných (neterminálnych) symbolov konkrétnymi konečnými (terminálnymi) symbolmi;
- Vždy definujeme neterminálny symbol, z ktorého vychádzame. Ak nezostane nič, čo by sme mohli nahradiť, máme výsledok;
Príklad
Poďme si gramatiku ukázať na príklade. Zadanie hovorí, že máme definovať gramatiku , ktorá bude generovať jednocifernú číslicu od nula po desať.
Našu gramatiku definujeme ako (v preklade: gramatika je štvorica eterminálnych a erminálnych symbolov s ravidlami a začiatočným neterminálnym symbolom - teda substitučným symbolom, s ktorým začíname - a tento symbol má označenie . Môžeme zvoliť akékoľvek označenie, ale najčastejšie sa používa S).
Teraz definujeme jednotlivé "písmená" z našej "NTPS" štvorice:
Čo zápis vyššie znamená?
- predstavuje množinu neterminálnych symbolov. Je to zoznam symbolov, ktoré môžeme nahradiť niečím iným.
- predstavuje množinu terminálnych symbolov. Sú to všetky symboly, z ktorých môže byť tvorené nejaké slovo
Ak ešte nechápeš čo sa tu deje, skúsime si to vysvetliť na pravidlách:
Definovali sme najdôležitejšiu časť každej gramatiky: pravidlá, pomocou ktorých sa symboly prepisujú na iné. Šípku () čítame ako "symbol x sa prepíše na y".
Úplná definícia našej gramatiky (ktorá generuje práve jednu číslicu od nula po desať) vyzerá nasledovne:
Poďme skúsiť vygenerovať čislicu 4. Za začiatočný neterminálny symbol sme zvolili (je to posledný symbol zo štvorice v definícií našej gramatiky , preto sme ho zvýraznili), takže týmto symbolom musíme aj začať. Čo bude nasledovať ďalej? Musíme tento symbol nahradiť niečím za šípkou v pravidlách (preto sa zápis "" číta ako "S sa prepíše na ..." - pretože sa skutočne prepíše na niečo iné... duh).
V zozname našich pravidiel vidíme pravidlo "". A to je vlastne všetko a máme číslicu 4 ktorú sme chceli. Musíme to ale matematicky zapísať:
Dôležité je použiť dvojitú šípku () namiesto jednoduchej (), pretože dvojitá šípka predstavuje takzvaný "krok odvodenia". Znamená to že sme prepísali neterminálny symbol S na 4. V jednom kroku môžeme použiť maximálne jedno pravidlo (teda, môžeme prepísať iba jeden neterminálny symbol na terminálny, nemôžme prepísať viacej symbolov naraz).
Slovo bolo vygenerované našou gramatikou správne, ak sa vo výsledku nenachádza žiadny neterminálny symbol (v našom prípade za neterminálny symbol podľa definície považujeme iba ). Vo výsledku sa za dvojitou šípkou nachádza iba 4, čo je symbol ktorý sme definovali v našej množine terminálnych symbolov (). Znamená to, že naše slovo "4" patrí do našej gramatiky , pretože tento výsledok obsahuje iba terminálne (konečné) symboly.
Čo dokážeme s gramatikou?
Príklad vyššie bol veľmi jednoduchý. Prepísali sme iba jeden neterminálny symbol na nejakú číslicu, a mali sme výsledné slovo z nášho jazyka číslic. Ale čo ak by sme mali za úlohu vytvoriť gramatiku ktorá bude generovať akékoľvek prirodzené číslo (celé číslo, ktoré je väčšie ako nula)?
Využijeme gramatiku z predchádzajúceho príkladu. Musíme ju avšak zmeniť tak, aby sme dokázali vygenerovať viac ako jeden symbol.
Skúsme sa pozrieť na takéto pravidlá:
Tieto pravidlá nám umožnia generovať číslo od 0 po 9. Avšak, ak musíme stále začať iba symbolom , pravidlá nám povolia tento symbol prepísať iba na jednu z týchto číslic - nedokážeme vygenerovať viacciferné čísla.
Ak by nás hneď nenapadlo riešenie, pravdepodobne by sme skúsili čísla nejako premiestniť na ľavú stranu (pred šípkou) aby sme nejako vygenerovali viac ako jednu číslicu a táto postupnosť by vytvorila číslo. Avšak, toto nie je povolené (podľa definície gramatiky musí ľavá strana vždy obsahovať neterminálny symbol, teda v tomto prípade naše ).
Riešenie v skutočnosti spočíva v rekurzií. Aby bolo riešenie čitateľné, musíme naše pravidlá trochu zmeniť:
Takto definované pravidlá patria gramatike, ktorá dokáže vygenerovať akékoľvek kladné celé číslo, ktoré neobsahuje nulu (zatiaľ sme tento prípad vynechali pre jednoduchosť). Pribudol nám nový neterminálny symbol (ako "číslo" - môžeme si zvoliť ľubovoľný symbol, dokonca by sme mohli pravidlá vyjadriť aj celým slovom, napríklad: , ale potom by bol zápis dlhý, preto to nebudeme komplikovať).
Zároveň sme pridali dve nové pravidlá pre neterminálny symbol , kde využívame rekurziu:
- Symbol sa môže prepísať na číslo , alebo sám na seba;
- Symbol sa môže prepísať na prázdne slovo (ktoré označujeme ako ).
Poďme skúsiť vyjadriť číslo "123":
To už vyzerá komplikovanejšie. Vysvetlíme si jednotlivé kroky:
- V prvom kroku sme začali so symbolom , ktorý sme prepísali na . Využili sme pritom prvé pravidlo (). Tým sme zabezpečili to, že môžeme nahradiť číslicou, za ktorou bude nasledovať ďalšie ;
- Za číslom ktoré sme nahradili nám zostalo opäť , s ktorým sme aj začínali. Preto môžeme spraviť presne to isté, a prepísať opäť na ;
- sme nahradili číslicou 2. Posledný krát spravíme to isté, čo v predchádzajúcich krokoch odvodenia a opäť nahradíme za ;
- Posledný neterminálny symbol (ktorý zostal z tretieho kroku) sme prepísali na číslicu 3, čo je posledná číslica ktorú potrebujeme aby sme vytvorili číslo "123". Avšak, zostal nám tam stále symbol , ktorý nasledoval za . Pre to, aby bolo naše číslo platné, tak výsledok nesmie obsahovať neterminálny symbol - musíme tento symbol nejako odstrániť.
- V tomto kroku využijeme druhé nové pravidlo, ktoré sme definovali () a prepíšeme na prázdne slovo . V tomto spočíva zmysel prázdneho slova, pretože predstavuje naozaj "nič" - už máme naše číslo 123, preto nahradíme "ničím", čím tento nadbytočný symbol v podstate odstránime;
- Výsledné slovo je "123". Toto číslo skutočne patrí do jazyka prirodzených čísel väčších ako nula, takže naša gramatika je definovaná správne.
Avšak, ak chceme povoliť aj generovanie čísiel ktoré obsahujú nulu, pravidlá musíme opäť upraviť. Tu je hlavným problémom to, že viacciferné čísla nemôžu začínať nulou, inak to sú neplatné čísla (napr.: nemôžme vytvoriť číslo "0123", nula na začiatok nepatrí).
Aby pravidiel nebolo priveľa, používa sa symbol "alebo" (zvyslá čiara: |
). Pravidlá vyššie teda môžeme zapísať aj ako:
Jedná sa o ekvivalentný zápis, ktorý je totožný s naším pôvodným zápisom. Pravidlá hovoria, že neterminálny symbol sa môže prepísať ako alebo (prázdne slovo). Ďalej sa môže prepísať na 1, alebo 2, až po 9.
Poďme ale konečne pridať pravidlo pre generovanie núl:
Začíname zo symbolu , ktorý sa môže prepísať na čísla od 1 po 9, za ktorými nasleduje . Tento symbol môžeme potom ľubovoľne kombinovať, až pokým ho nenahradíme prázdnym slovom, čo ukončí generovanie nášho slova.